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;

    }

 

posted @ 2013-11-15 00:14  山顶的鱼  阅读(183)  评论(0编辑  收藏  举报