Android实现人人网点击“+”弹出效果
最近没日没夜的加班,加得连自己姓什么都忘记了,更可怕的是测试出一个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; }