Android实现人人网点击“+”弹出效果
转载:http://blog.csdn.net/jiahui524/article/details/7376180
最近没日没夜的加班,加得连自己姓什么都忘记了,更可怕的是测试出一个BUG还要扣工资!唉,先不谈工作的事了吧。还是回到技术上来,每天也就这么点精神粮食来满足自己了,最近又有很多的东西忘记跟大家分享了,俺又回来,继续分享菜鸟的另一个新的发现,希望能帮助更多的人来实现自己的项目中的一些需要。不管你们有没有这样的需求,我只希望能帮助到大家吧,也希望大家能分享自己的东西,帮助更多的人,让我们菜鸟共同成长!
继续以前的博客风格,先上效果图再上代码,有图有真相!
实现效果:
实现思路:
大家看到这个效果是不是特别的熟悉呀,呵呵,就是人人网的里面的一个效果,同样发现现在很多的应用都用到了这样的效果,像最近出来的关于日程分享的UPTO的一款苹果应用,大家有空可以去看下,那上面还有一个比较炫的效果还没有好好的研究。
有些人可能也在哪见过这样的效果,像通讯录中用到了QuickBar,但那个不灵活,要实现这样的效果其实我们又用到了PopupWindow。有关于这方面的文章,有一个博客也介绍得很清楚,我只是在他的基础上加一下功能。突然发现这个东西还是灰常的好用哈。
我们需要重写PopupWindow。然后通过setContentView()来加载我们的布局文件,然后再加个动画就实现了人人网的一模一样的效果了。
给出重写PopupWindow的代码,有什么不懂的自己看代码吧或者加QQ交流下。
- package com.jiahui.view;
- import java.util.ArrayList;
- import android.content.Context;
- import android.graphics.Rect;
- import android.graphics.drawable.BitmapDrawable;
- import android.graphics.drawable.Drawable;
- import android.view.Gravity;
- import android.view.LayoutInflater;
- import android.view.MotionEvent;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.view.View.OnTouchListener;
- import android.view.ViewGroup;
- import android.view.ViewGroup.LayoutParams;
- import android.view.WindowManager;
- import android.view.animation.Animation;
- import android.view.animation.AnimationUtils;
- import android.view.animation.Interpolator;
- import android.widget.ImageView;
- import android.widget.LinearLayout;
- import android.widget.PopupWindow;
- import android.widget.TextView;
- import com.jiahui.quickbar.ActionItem;
- import com.jiahui.quickbar.R;
- /**
- * 重写popupWindow
- * @author Administrator
- *
- */
- public class QuickActionBar extends PopupWindow {
- private View root;
- private ImageView mArrowUp;
- private ImageView mArrowDown;
- private Animation mTrackAnim;
- private LayoutInflater inflater;
- private Context context;
- private View anchor;
- private PopupWindow window;
- private Drawable background = null;
- private WindowManager windowManager;
- public static final int ANIM_GROW_FROM_LEFT = 1;
- public static final int ANIM_GROW_FROM_RIGHT = 2;
- public static final int ANIM_GROW_FROM_CENTER = 3;
- public static final int ANIM_AUTO = 4;
- private int animStyle;
- private boolean animateTrack;
- private ViewGroup mTrack;
- private ArrayList<ActionItem> actionItems;
- public QuickActionBar(View anchor) {
- super(anchor);
- this.anchor = anchor;
- this.window = new PopupWindow(anchor.getContext());
- /**
- * 在popwindow外点击即关闭该window
- */
- window.setTouchInterceptor(new OnTouchListener() {
- @Override
- public boolean onTouch(View view, MotionEvent event) {
- if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
- // 让其消失
- QuickActionBar.this.window.dismiss();
- return true;
- }
- return false;
- }
- });
- context = anchor.getContext();
- windowManager = (WindowManager) context
- .getSystemService(Context.WINDOW_SERVICE);
- actionItems = new ArrayList<ActionItem>();
- inflater = (LayoutInflater) context
- .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- root = (ViewGroup) inflater.inflate(R.layout.quickbar, null);
- // 上下两个箭头
- mArrowDown = (ImageView) root.findViewById(R.id.arrow_down);
- mArrowUp = (ImageView) root.findViewById(R.id.arrow_up);
- setContentView(root);
- mTrackAnim = AnimationUtils.loadAnimation(context, R.anim.rail);
- /**
- * 设置加速效果
- */
- mTrackAnim.setInterpolator(new Interpolator() {
- @Override
- public float getInterpolation(float t) {
- final float inner = (t * 1.55f) - 1.1f;
- return 1.2f - inner * inner;
- }
- });
- // 这个是弹出窗口内的水平布局
- mTrack = (ViewGroup) root.findViewById(R.id.tracks);
- animStyle = ANIM_AUTO;// 设置动画风格
- animateTrack = true;
- }
- /**
- * 设置一个flag 来标识动画显示
- *
- * @param animateTrack
- */
- public void animateTrack(boolean animateTrack) {
- this.animateTrack = animateTrack;
- }
- /**
- * 设置动画风格
- *
- * @param animStyle
- */
- public void setAnimStyle(int animStyle) {
- this.animStyle = animStyle;
- }
- /**
- * 增加一个Action
- *
- * @param actionItem
- */
- public void addActionItem(ActionItem actionItem) {
- actionItems.add(actionItem);
- }
- /**
- * 弹出窗体
- */
- public void show() {
- preShow();
- int[] location = new int[2];
- // 得到anchor的位置
- anchor.getLocationOnScreen(location);
- // 以anchor的位置构造一个矩形
- Rect anchorRect = new Rect(location[0], location[1], location[0]
- + anchor.getWidth(), location[1] + anchor.getHeight());
- root.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
- LayoutParams.WRAP_CONTENT));
- root.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
- int rootWidth = root.getMeasuredWidth();
- int rootHeight = root.getMeasuredHeight();
- // 得到屏幕的宽
- int screenWidth = windowManager.getDefaultDisplay().getWidth();
- // 设置弹窗弹出的位置的X y
- int xPos = (screenWidth - rootWidth) / 2;
- int yPos = anchorRect.top - rootHeight;
- boolean onTop = true;
- // 在底部弹出
- if (rootHeight > anchorRect.top) {
- yPos = anchorRect.bottom;
- onTop = false;
- }
- // 根据弹出位置,设置不同的方向箭头图片
- // showArrow(((onTop) ? R.id.arrow_down : R.id.arrow_up),
- // anchorRect.centerX());
- // 设置弹出动画风格
- setAnimationStyle(screenWidth, anchorRect.centerX(), onTop);
- // 创建action list
- createActionList();
- // 在指定位置弹出弹窗
- window.showAtLocation(this.anchor, Gravity.NO_GRAVITY, xPos, yPos);
- // 设置弹窗内部的水平布局的动画
- if (animateTrack) {
- mTrack.startAnimation(mTrackAnim);
- }
- }
- /**
- * 预处理窗口
- */
- protected void preShow() {
- if (root == null) {
- throw new IllegalStateException("需要为弹窗设置布局");
- }
- if (background == null) {
- window.setBackgroundDrawable(new BitmapDrawable());
- } else {
- window.setBackgroundDrawable(background);
- }
- // 设置宽度
- window.setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
- // 设置高度
- window.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
- window.setTouchable(true);
- window.setFocusable(true);
- window.setOutsideTouchable(true);
- // 指定布局
- window.setContentView(root);
- }
- /**
- * 设置动画风格
- *
- * @param screenWidth
- * @param requestedX
- * @param onTop
- */
- private void setAnimationStyle(int screenWidth, int requestedX,
- boolean onTop) {
- int arrowPos = requestedX - mArrowUp.getMeasuredWidth() / 2;
- switch (animStyle) {
- case ANIM_GROW_FROM_LEFT:
- window.setAnimationStyle((onTop) ? R.style.Animations_PopDownMenu_Left
- : R.style.Animations_PopDownMenu_Left);
- break;
- case ANIM_GROW_FROM_RIGHT:
- window.setAnimationStyle((onTop) ? R.style.Animations_PopDownMenu_Right
- : R.style.Animations_PopDownMenu_Right);
- break;
- case ANIM_GROW_FROM_CENTER:
- window.setAnimationStyle((onTop) ? R.style.Animations_PopDownMenu_Center
- : R.style.Animations_PopDownMenu_Center);
- break;
- case ANIM_AUTO:
- if (arrowPos < screenWidth / 4) {
- window.setAnimationStyle((onTop) ? R.style.Animations_PopDownMenu_Left
- : R.style.Animations_PopDownMenu_Left);
- } else if (arrowPos > screenWidth / 4
- && arrowPos < 3 * (screenWidth / 4)) {
- window.setAnimationStyle((onTop) ? R.style.Animations_PopDownMenu_Center
- : R.style.Animations_PopDownMenu_Center);
- } else {
- window.setAnimationStyle((onTop) ? R.style.Animations_PopDownMenu_Right
- : R.style.Animations_PopDownMenu_Right);
- }
- break;
- }
- }
- /**
- * 创建Action List
- */
- private void createActionList() {
- View view;
- String title;
- Drawable icon;
- OnClickListener clickListener;
- int index = 1;
- for (int i = 0; i < actionItems.size(); i++) {
- title = actionItems.get(i).getTitle();
- icon = actionItems.get(i).getIcon();
- clickListener = actionItems.get(i).getClickListener();
- // 得到Action item
- view = getActionItem(title, icon, clickListener);
- view.setFocusable(true);
- view.setClickable(true);
- mTrack.addView(view, index);
- index++;
- }
- }
- /**
- * 得到Action Item
- *
- * @param title
- * @param icon
- * @param listener
- * @return
- */
- private View getActionItem(String title, Drawable icon,
- OnClickListener listener) {
- // 装载Action布局
- LinearLayout linearLayout = (LinearLayout) inflater.inflate(
- R.layout.action_item, null);
- ImageView img_icon = (ImageView) linearLayout.findViewById(R.id.icon);
- TextView tv_title = (TextView) linearLayout.findViewById(R.id.title);
- if (img_icon != null) {
- img_icon.setImageDrawable(icon);
- } else {
- img_icon.setVisibility(View.GONE);
- }
- if (tv_title != null) {
- tv_title.setText(title);
- } else {
- tv_title.setOnClickListener(listener);
- }
- return linearLayout;
- }
- // /**
- // * 显示箭头
- // *
- // * @param whichArrow箭头资源id
- // * @param requestedX
- // * 距离屏幕左边的距离
- // */
- // private void showArrow(int whichArrow, int requestedX) {
- //
- // final View showArrow = (whichArrow == R.id.arrow_up) ? mArrowUp
- // : mArrowDown;
- // final View hideArrow = (whichArrow == R.id.arrow_up) ? mArrowDown
- // : mArrowUp;
- // final int arrowWidth = mArrowUp.getMeasuredWidth();
- // showArrow.setVisibility(View.VISIBLE);
- // ViewGroup.MarginLayoutParams param = (ViewGroup.MarginLayoutParams)
- // showArrow
- // .getLayoutParams();
- // // 以此设置距离左边的距离
- // param.leftMargin = requestedX - arrowWidth / 2;
- // hideArrow.setVisibility(View.INVISIBLE);
- //
- // }
- }
这里只贴出核心代码了,其他代码的话自己可以下载源代码研究下,继续我的风格,放出自己的源代码与大家分享,希望能帮助到大家一点。
如需转载引用请注明出处:http://blog.csdn.net/jiahui524
欢迎大家多多交流。分享为快乐之本!让我们菜鸟一起成长!
提供源代码下载 :http://download.csdn.net/detail/jiahui524/4158447
PS:有网友近来提问,说ActionItem的点击事件无法完成,这也算是我的一个失误,识人子弟了,在此我向大家表示抱歉,也感谢那位网友的提问。如果想要ActionItem的事件有效,在原来的源代码中的QuickActionBar里的找到getActionItem方法修改代码如下:
- /**
- * 得到Action Item
- *
- * @param title
- * @param icon
- * @param listener
- * @return
- */
- private View getActionItem(String title, Drawable icon,
- OnClickListener listener) {
- // 装载Action布局
- LinearLayout linearLayout = (LinearLayout) inflater.inflate(
- R.layout.action_item, null);
- ImageView img_icon = (ImageView) linearLayout.findViewById(R.id.icon);
- TextView tv_title = (TextView) linearLayout.findViewById(R.id.title);
- if (img_icon != null) {
- img_icon.setImageDrawable(icon);
- } else {
- img_icon.setVisibility(View.GONE);
- }
- if (tv_title != null) {
- tv_title.setText(title);
- } else {
- tv_title.setOnClickListener(listener);
- }
- if (listener != null) {
- linearLayout.setOnClickListener(listener);
- }
- return linearLayout;
- }