Android实现人人网点击“+”弹出效果

转载 2012年03月22日 00:30:33

最近没日没夜的加班,加得连自己姓什么都忘记了,更可怕的是测试出一个BUG还要扣工资!唉,先不谈工作的事了吧。还是回到技术上来,每天也就这么点精神粮食来满足自己了,最近又有很多的东西忘记跟大家分享了,俺又回来,继续分享菜鸟的另一个新的发现,希望能帮助更多的人来实现自己的项目中的一些需要。不管你们有没有这样的需求,我只希望能帮助到大家吧,也希望大家能分享自己的东西,帮助更多的人,让我们菜鸟共同成长!

继续以前的博客风格,先上效果图再上代码,有图有真相!

实现效果:


实现思路:

大家看到这个效果是不是特别的熟悉呀,呵呵,就是人人网的里面的一个效果,同样发现现在很多的应用都用到了这样的效果,像最近出来的关于日程分享的UPTO的一款苹果应用,大家有空可以去看下,那上面还有一个比较炫的效果还没有好好的研究。

有些人可能也在哪见过这样的效果,像通讯录中用到了QuickBar,但那个不灵活,要实现这样的效果其实我们又用到了PopupWindow。有关于这方面的文章,有一个博客也介绍得很清楚,我只是在他的基础上加一下功能。突然发现这个东西还是灰常的好用哈。

我们需要重写PopupWindow。然后通过setContentView()来加载我们的布局文件,然后再加个动画就实现了人人网的一模一样的效果了。

给出重写PopupWindow的代码,有什么不懂的自己看代码吧或者加QQ交流下。

  1. package com.jiahui.view;  
  2.   
  3. import java.util.ArrayList;  
  4.   
  5. import android.content.Context;  
  6. import android.graphics.Rect;  
  7. import android.graphics.drawable.BitmapDrawable;  
  8. import android.graphics.drawable.Drawable;  
  9. import android.view.Gravity;  
  10. import android.view.LayoutInflater;  
  11. import android.view.MotionEvent;  
  12. import android.view.View;  
  13. import android.view.View.OnClickListener;  
  14. import android.view.View.OnTouchListener;  
  15. import android.view.ViewGroup;  
  16. import android.view.ViewGroup.LayoutParams;  
  17. import android.view.WindowManager;  
  18. import android.view.animation.Animation;  
  19. import android.view.animation.AnimationUtils;  
  20. import android.view.animation.Interpolator;  
  21. import android.widget.ImageView;  
  22. import android.widget.LinearLayout;  
  23. import android.widget.PopupWindow;  
  24. import android.widget.TextView;  
  25.   
  26. import com.jiahui.quickbar.ActionItem;  
  27. import com.jiahui.quickbar.R;  
  28.   
  29. /** 
  30.  * 重写popupWindow 
  31.  * @author Administrator 
  32.  * 
  33.  */  
  34. public class QuickActionBar extends PopupWindow {  
  35.   
  36.     private View root;  
  37.   
  38.     private ImageView mArrowUp;  
  39.   
  40.     private ImageView mArrowDown;  
  41.   
  42.     private Animation mTrackAnim;  
  43.   
  44.     private LayoutInflater inflater;  
  45.   
  46.     private Context context;  
  47.   
  48.     private View anchor;  
  49.   
  50.     private PopupWindow window;  
  51.   
  52.     private Drawable background = null;  
  53.   
  54.     private WindowManager windowManager;  
  55.   
  56.     public static final int ANIM_GROW_FROM_LEFT = 1;  
  57.   
  58.     public static final int ANIM_GROW_FROM_RIGHT = 2;  
  59.   
  60.     public static final int ANIM_GROW_FROM_CENTER = 3;  
  61.   
  62.     public static final int ANIM_AUTO = 4;  
  63.   
  64.     private int animStyle;  
  65.     private boolean animateTrack;  
  66.     private ViewGroup mTrack;  
  67.     private ArrayList<ActionItem> actionItems;  
  68.   
  69.     public QuickActionBar(View anchor) {  
  70.   
  71.         super(anchor);  
  72.   
  73.         this.anchor = anchor;  
  74.   
  75.         this.window = new PopupWindow(anchor.getContext());  
  76.   
  77.         /** 
  78.          * 在popwindow外点击即关闭该window 
  79.          */  
  80.         window.setTouchInterceptor(new OnTouchListener() {  
  81.   
  82.             @Override  
  83.             public boolean onTouch(View view, MotionEvent event) {  
  84.   
  85.                 if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {  
  86.   
  87.                     // 让其消失   
  88.                     QuickActionBar.this.window.dismiss();  
  89.   
  90.                     return true;  
  91.   
  92.                 }  
  93.   
  94.                 return false;  
  95.             }  
  96.         });  
  97.   
  98.         context = anchor.getContext();  
  99.   
  100.         windowManager = (WindowManager) context  
  101.                 .getSystemService(Context.WINDOW_SERVICE);  
  102.   
  103.         actionItems = new ArrayList<ActionItem>();  
  104.   
  105.         inflater = (LayoutInflater) context  
  106.                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);  
  107.   
  108.         root = (ViewGroup) inflater.inflate(R.layout.quickbar, null);  
  109.   
  110.         // 上下两个箭头   
  111.         mArrowDown = (ImageView) root.findViewById(R.id.arrow_down);  
  112.         mArrowUp = (ImageView) root.findViewById(R.id.arrow_up);  
  113.   
  114.         setContentView(root);  
  115.   
  116.         mTrackAnim = AnimationUtils.loadAnimation(context, R.anim.rail);  
  117.   
  118.         /** 
  119.          * 设置加速效果 
  120.          */  
  121.         mTrackAnim.setInterpolator(new Interpolator() {  
  122.   
  123.             @Override  
  124.             public float getInterpolation(float t) {  
  125.                 final float inner = (t * 1.55f) - 1.1f;  
  126.                 return 1.2f - inner * inner;  
  127.             }  
  128.         });  
  129.   
  130.         // 这个是弹出窗口内的水平布局   
  131.         mTrack = (ViewGroup) root.findViewById(R.id.tracks);  
  132.   
  133.         animStyle = ANIM_AUTO;// 设置动画风格   
  134.   
  135.         animateTrack = true;  
  136.   
  137.     }  
  138.   
  139.     /** 
  140.      * 设置一个flag 来标识动画显示 
  141.      *  
  142.      * @param animateTrack 
  143.      */  
  144.     public void animateTrack(boolean animateTrack) {  
  145.         this.animateTrack = animateTrack;  
  146.     }  
  147.   
  148.     /** 
  149.      * 设置动画风格 
  150.      *  
  151.      * @param animStyle 
  152.      */  
  153.     public void setAnimStyle(int animStyle) {  
  154.         this.animStyle = animStyle;  
  155.     }  
  156.   
  157.     /** 
  158.      * 增加一个Action 
  159.      *  
  160.      * @param actionItem 
  161.      */  
  162.     public void addActionItem(ActionItem actionItem) {  
  163.         actionItems.add(actionItem);  
  164.     }  
  165.   
  166.     /** 
  167.      * 弹出窗体 
  168.      */  
  169.     public void show() {  
  170.   
  171.         preShow();  
  172.   
  173.         int[] location = new int[2];  
  174.   
  175.         // 得到anchor的位置   
  176.         anchor.getLocationOnScreen(location);  
  177.   
  178.         // 以anchor的位置构造一个矩形   
  179.         Rect anchorRect = new Rect(location[0], location[1], location[0]  
  180.                 + anchor.getWidth(), location[1] + anchor.getHeight());  
  181.   
  182.         root.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,  
  183.                 LayoutParams.WRAP_CONTENT));  
  184.         root.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);  
  185.   
  186.         int rootWidth = root.getMeasuredWidth();  
  187.         int rootHeight = root.getMeasuredHeight();  
  188.   
  189.         // 得到屏幕的宽   
  190.         int screenWidth = windowManager.getDefaultDisplay().getWidth();  
  191.   
  192.         // 设置弹窗弹出的位置的X y   
  193.         int xPos = (screenWidth - rootWidth) / 2;  
  194.         int yPos = anchorRect.top - rootHeight;  
  195.   
  196.         boolean onTop = true;  
  197.         // 在底部弹出   
  198.         if (rootHeight > anchorRect.top) {  
  199.             yPos = anchorRect.bottom;  
  200.             onTop = false;  
  201.         }  
  202.   
  203.         // 根据弹出位置,设置不同的方向箭头图片   
  204.         // showArrow(((onTop) ? R.id.arrow_down : R.id.arrow_up),   
  205.         // anchorRect.centerX());   
  206.   
  207.         // 设置弹出动画风格   
  208.         setAnimationStyle(screenWidth, anchorRect.centerX(), onTop);  
  209.         // 创建action list   
  210.         createActionList();  
  211.         // 在指定位置弹出弹窗   
  212.         window.showAtLocation(this.anchor, Gravity.NO_GRAVITY, xPos, yPos);  
  213.   
  214.         // 设置弹窗内部的水平布局的动画   
  215.         if (animateTrack) {  
  216.             mTrack.startAnimation(mTrackAnim);  
  217.         }  
  218.   
  219.     }  
  220.   
  221.     /** 
  222.      * 预处理窗口 
  223.      */  
  224.     protected void preShow() {  
  225.   
  226.         if (root == null) {  
  227.             throw new IllegalStateException("需要为弹窗设置布局");  
  228.         }  
  229.   
  230.         if (background == null) {  
  231.             window.setBackgroundDrawable(new BitmapDrawable());  
  232.         } else {  
  233.             window.setBackgroundDrawable(background);  
  234.         }  
  235.   
  236.         // 设置宽度   
  237.         window.setWidth(WindowManager.LayoutParams.WRAP_CONTENT);  
  238.         // 设置高度   
  239.         window.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);  
  240.   
  241.         window.setTouchable(true);  
  242.         window.setFocusable(true);  
  243.         window.setOutsideTouchable(true);  
  244.   
  245.         // 指定布局   
  246.         window.setContentView(root);  
  247.   
  248.     }  
  249.   
  250.     /** 
  251.      * 设置动画风格 
  252.      *  
  253.      * @param screenWidth 
  254.      * @param requestedX 
  255.      * @param onTop 
  256.      */  
  257.     private void setAnimationStyle(int screenWidth, int requestedX,  
  258.             boolean onTop) {  
  259.   
  260.         int arrowPos = requestedX - mArrowUp.getMeasuredWidth() / 2;  
  261.         switch (animStyle) {  
  262.         case ANIM_GROW_FROM_LEFT:  
  263.   
  264.             window.setAnimationStyle((onTop) ? R.style.Animations_PopDownMenu_Left  
  265.                     : R.style.Animations_PopDownMenu_Left);  
  266.   
  267.             break;  
  268.   
  269.         case ANIM_GROW_FROM_RIGHT:  
  270.   
  271.             window.setAnimationStyle((onTop) ? R.style.Animations_PopDownMenu_Right  
  272.                     : R.style.Animations_PopDownMenu_Right);  
  273.   
  274.             break;  
  275.   
  276.         case ANIM_GROW_FROM_CENTER:  
  277.             window.setAnimationStyle((onTop) ? R.style.Animations_PopDownMenu_Center  
  278.                     : R.style.Animations_PopDownMenu_Center);  
  279.   
  280.             break;  
  281.   
  282.         case ANIM_AUTO:  
  283.   
  284.             if (arrowPos < screenWidth / 4) {  
  285.                 window.setAnimationStyle((onTop) ? R.style.Animations_PopDownMenu_Left  
  286.                         : R.style.Animations_PopDownMenu_Left);  
  287.   
  288.             } else if (arrowPos > screenWidth / 4  
  289.                     && arrowPos < 3 * (screenWidth / 4)) {  
  290.                 window.setAnimationStyle((onTop) ? R.style.Animations_PopDownMenu_Center  
  291.                         : R.style.Animations_PopDownMenu_Center);  
  292.             } else {  
  293.                 window.setAnimationStyle((onTop) ? R.style.Animations_PopDownMenu_Right  
  294.                         : R.style.Animations_PopDownMenu_Right);  
  295.             }  
  296.   
  297.             break;  
  298.   
  299.         }  
  300.   
  301.     }  
  302.   
  303.     /** 
  304.      * 创建Action List 
  305.      */  
  306.     private void createActionList() {  
  307.   
  308.         View view;  
  309.   
  310.         String title;  
  311.   
  312.         Drawable icon;  
  313.   
  314.         OnClickListener clickListener;  
  315.   
  316.         int index = 1;  
  317.         for (int i = 0; i < actionItems.size(); i++) {  
  318.   
  319.             title = actionItems.get(i).getTitle();  
  320.             icon = actionItems.get(i).getIcon();  
  321.   
  322.             clickListener = actionItems.get(i).getClickListener();  
  323.   
  324.             // 得到Action item   
  325.             view = getActionItem(title, icon, clickListener);  
  326.             view.setFocusable(true);  
  327.             view.setClickable(true);  
  328.   
  329.             mTrack.addView(view, index);  
  330.   
  331.             index++;  
  332.         }  
  333.   
  334.     }  
  335.   
  336.     /** 
  337.      * 得到Action Item 
  338.      *  
  339.      * @param title 
  340.      * @param icon 
  341.      * @param listener 
  342.      * @return 
  343.      */  
  344.     private View getActionItem(String title, Drawable icon,  
  345.             OnClickListener listener) {  
  346.   
  347.         // 装载Action布局   
  348.   
  349.         LinearLayout linearLayout = (LinearLayout) inflater.inflate(  
  350.                 R.layout.action_item, null);  
  351.   
  352.         ImageView img_icon = (ImageView) linearLayout.findViewById(R.id.icon);  
  353.   
  354.         TextView tv_title = (TextView) linearLayout.findViewById(R.id.title);  
  355.   
  356.         if (img_icon != null) {  
  357.             img_icon.setImageDrawable(icon);  
  358.   
  359.         } else {  
  360.             img_icon.setVisibility(View.GONE);  
  361.         }  
  362.   
  363.         if (tv_title != null) {  
  364.             tv_title.setText(title);  
  365.         } else {  
  366.             tv_title.setOnClickListener(listener);  
  367.         }  
  368.   
  369.         return linearLayout;  
  370.   
  371.     }  
  372.   
  373.     // /**   
  374.     // * 显示箭头   
  375.     // *   
  376.     // * @param whichArrow箭头资源id   
  377.     // * @param requestedX   
  378.     // * 距离屏幕左边的距离   
  379.     // */   
  380.     // private void showArrow(int whichArrow, int requestedX) {   
  381.     //   
  382.     // final View showArrow = (whichArrow == R.id.arrow_up) ? mArrowUp   
  383.     // : mArrowDown;   
  384.     // final View hideArrow = (whichArrow == R.id.arrow_up) ? mArrowDown   
  385.     // : mArrowUp;   
  386.     // final int arrowWidth = mArrowUp.getMeasuredWidth();   
  387.     // showArrow.setVisibility(View.VISIBLE);   
  388.     // ViewGroup.MarginLayoutParams param = (ViewGroup.MarginLayoutParams)   
  389.     // showArrow   
  390.     // .getLayoutParams();   
  391.     // // 以此设置距离左边的距离   
  392.     // param.leftMargin = requestedX - arrowWidth / 2;   
  393.     // hideArrow.setVisibility(View.INVISIBLE);   
  394.     //   
  395.     // }   
  396.   
  397. }  

这里只贴出核心代码了,其他代码的话自己可以下载源代码研究下,继续我的风格,放出自己的源代码与大家分享,希望能帮助到大家一点。

如需转载引用请注明出处:http://blog.csdn.net/jiahui524

欢迎大家多多交流。分享为快乐之本!让我们菜鸟一起成长!

提供源代码下载 :http://download.csdn.net/detail/jiahui524/4158447

Android实现人人网点击“+”弹出效果

最近没日没夜的加班,加得连自己姓什么都忘记了,更可怕的是测试出一个BUG还要扣工资!唉,先不谈工作的事了吧。还是回到技术上来,每天也就这么点精神粮食来满足自己了,最近又有很多的东西忘记跟大家分享了,俺...

Android实现人人网点击“+”弹出效果

最近没日没夜的加班,加得连自己姓什么都忘记了,更可怕的是测试出一个BUG还要扣工资!唉,先不谈工作的事了吧。还是回到技术上来,每天也就这么点精神粮食来满足自己了,最近又有很多的东西忘记跟大家分享了,俺...

Android---文本中缩略图点击弹出大图效果实现

Android---文本中缩略图点击弹出大图效果实现转自http://www.cnblogs.com/jico/archive/2011/02/25/1965258.html很久没有写博客了,这两天一...

Android开发之文本中缩略图点击弹出大图效果实现

首先来张效果图,没有经过美工处理的 实现基本功能 其实做这个项目复习了很多内容,将之前单个项目中用到的某些功能综合到一起了,例如1、自定义标题栏2、Java和JavaScript的互调3...

Android滑动菜单特效实现,仿人人客户端侧滑效果

请先去看一遍之前的文章 Android滑动菜单特效实现,仿人人客户端侧滑效果,史上最简单的侧滑实现 ,因为我们今天要实现的滑动菜单框架也是基于同样的原理的。 之前的文章中在最后也提到了,如果是你...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android实现人人网点击“+”弹出效果
举报原因:
原因补充:

(最多只允许输入30个字)