Android——PopupWindow(泡泡)初体验

来源:互联网 发布:java base64 aes加密 编辑:程序博客网 时间:2024/05/02 00:58

        项目中有个类似朋友圈点击评论按钮的弹框的需求,一开始直接将点击评论显示出来的内容放到布局文件中默认隐藏,点击之后显示出来。花了好一段时间功能做出来了,却发现其他地方也要用到这个功能。狂晕!!!!

        我也知道做这个功能最好使用PopupWindow来做,无赖开始做不熟练PopupWindow。结果为了代码方便在其他地方使用,还得换回PopupWindow。。经过将近一天的研究,对PopupWindow有了点了解。话不多说,开始具体讲解PopupWindow。


先上图,大致是点击上面或者下面的图标会弹出一个框:


        PopupWindow一些原理性的东西也是没有搞懂,只是自己目前有了解的一些位置问题和添加动画等等记录一下。这里就讲下面有三个选项的例子。

下面是将要在PopupWindow中显示的内容布局,布局很简单,没什么说的:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/adddynamic_normal"
    android:gravity="center"
    android:orientation="horizontal">

        <LinearLayout
                android:id="@+id/imgPraise"
                 android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                 android:background="@drawable/bg_comments_item"
                android:clickable="true"
                android:gravity="center"
                android:orientation="horizontal"
                android:paddingBottom="@dimen/size_h2"
                android:paddingLeft="@dimen/size_h2"
                android:paddingTop="@dimen/size_h2" >

        <ImageView
            android:layout_width="@dimen/size_h1"
            android:layout_height="@dimen/size_h1"
            android:src="@drawable/ic_favorite_outline_white" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="喜欢"
            android:textColor="@color/white"
            android:textSize="@dimen/general_text_h3" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/imgReply"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:background="@drawable/bg_comments_item"
        android:clickable="true"
        android:gravity="center"
        android:orientation="horizontal"
        android:paddingBottom="@dimen/size_h2"
        android:paddingLeft="@dimen/size_h3"
        android:paddingRight="@dimen/size_h3"
        android:paddingTop="@dimen/size_h2" >

        <ImageView
            android:layout_width="@dimen/size_h1"
            android:layout_height="@dimen/size_h1"
            android:src="@drawable/ic_textsms_white" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="评论"
            android:textColor="@color/white"
            android:textSize="@dimen/general_text_h3" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/llShare"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:background="@drawable/bg_comments_item"
        android:clickable="true"
        android:gravity="center"
        android:orientation="horizontal"
        android:paddingBottom="@dimen/size_h2"
        android:paddingLeft="@dimen/size_h4"
        android:paddingRight="@dimen/size_h2"
        android:paddingTop="@dimen/size_h2" >

        <ImageView
            android:layout_width="@dimen/size_h1"
            android:layout_height="@dimen/size_h1"
            android:src="@drawable/ic_share_white" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="分享"
            android:textColor="@color/white"
            android:textSize="@dimen/general_text_h3" />
    </LinearLayout>

</LinearLayout>

接下来就是PopupWindow显示和消失的动画——动画用xml文件配置,具体怎样使用xml文件配置动画效果这里也不细说,又不懂了自己查找资料。这里的动画效果是缩放和透明度同时执行:


style.xml文件:

    <!-- 班级圈点击评论按钮执行的动画 -->
    <style name="popupAnimation_comments" parent="android:Animation">
        <item name="android:windowEnterAnimation">@anim/comments_in</item>
        <item name="android:windowExitAnimation">@anim/comments_out</item> 
    </style>


comments_in.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <scale
        android:duration="150"
        android:fillAfter="false"
        android:fromXScale="0.5"
        android:fromYScale="0.5"
        android:pivotX="85.0%"
        android:pivotY="20.000004%"
        android:toXScale="1.0"
        android:toYScale="1.0" />


    <alpha
        android:duration="150"
        android:fillAfter="false"
        android:fromAlpha="0.2"
        android:toAlpha="1.0" />
</set>


comments_out.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <scale
        android:duration="150"
        android:fillAfter="false"
        android:fromXScale="1.0"
        android:fromYScale="1.0"
        android:pivotX="85.0%"
        android:pivotY="20.000004%"
        android:toXScale="0.5"
        android:toYScale="0.5" />

    <alpha
        android:duration="150"
        android:fillAfter="false"
        android:fromAlpha="1.0"
        android:toAlpha="0.2" />
</set>


接下来就是PopupWindow的代码:

public class ShowCommentsPopupWindow {
        public PopupWindow popWindow; //内含PopupWindow对象
        private Context context;
        private int animationStyle;  //动画的ID(传值为R.Style.xxxxx类型)

        public ShowCommentsPopupWindow(Context context,int animationStyle ) {
                this.context = context;
                this.animationStyle = animationStyle;
        }

        /**
        * 显示PopupWindow的方法
        * @param parent:PopupWindow显示位置的依赖View
        * @param layoutResource:PopupWindow显示内容的布局id
        * @param layoutDpWidth:布局的宽(传递dp尺寸值)
        * @param layoutDpHeight:布局的高(传递dp尺寸值)
        */

        public void showPopup(View parent , int layoutResource,float layoutDpWidth , float layoutDpHeight) {

                if (popWindow == null) {
                        LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                        View view = layoutInflater.inflate(layoutResource,null);

                        //dp与px转换
                        int width = dip2px(context, layoutDpWidth);
                        int height = dip2px(context, layoutDpHeight);

                        //实例化PopupWindow:参数分别位显示内容、弹框的宽、高、是否可以获得焦点
                        popWindow = new PopupWindow(view, width, height, true);
                }

                //设置PopupWindow出来与消失的动画
                popWindow.setAnimationStyle(animationStyle);

                //设置外界可以点击
                popWindow.setOutsideTouchable(false);
                popWindow.setBackgroundDrawable(new BitmapDrawable());
                popWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);

                //显示位置设置
                int xoff = -popWindow.getWidth() - 5;
                int yoff = -((popWindow.getHeight() - parent.getHeight()) / 2)- parent.getHeight();
                popWindow.showAsDropDown(parent, xoff, yoff);


                popWindow.setOnDismissListener(new OnDismissListener() {
                @Override
                public void onDismiss() {
                }
        });


        popWindow.setTouchInterceptor(new OnTouchListener() {
                                public boolean onTouch(View view, MotionEvent event) {
                                return false;
                                }
                        });
        }



                /**
                * dp换算成px
                */

                public static int dip2px(Context context, float dpValue) {
                        final float scale = context.getResources().getDisplayMetrics().density;
                        return (int) (dpValue * scale + 0.5f);
                }


                /**
                *  px换算成dp
                */

                public static int px2dip(Context context, float pxValue) {
                        final float scale = context.getResources().getDisplayMetrics().density;
                        return (int) (pxValue / scale + 0.5f);
                }
        }

这里要强调的是显示位置的问题,设置显示有两种方法:

showAtLocation(View parent, int gravity, int x, int y)
这种方法指定一个父控件,参数2指定PopupWindow显示的样式,其他两个参数指定PopupWindow的左上角相对父控件左上角(默认左上角与父控件的左上角对齐)的x、y偏移量
showAsDropDown(View anchor, int xoff, int yoff)
这种方法随机指定一个控件作为基准,默认与指定控件左上角对齐。后两个参数指定偏移量(往左或者往上的值是负数,这很容易理解)。

这里需要特别强调的是:

如果PopupWindow实例化时的宽高参数指定为:LinearLayout.LayoutParams.WRAP_CONTENT,在绘制前是不能通过popWindow.getWidth()或者popWindow.getHeight()得到宽高,你会看到他们都返回-2。在没有绘制完这些方法都是不能用的。
所以为了解决这个问题,我的做法也只是调用方法的时候动态指定要显示内容的宽高。

这个也是我目前觉得不够完善的地方之一,以后想到了在说出来

另一个不够完善的地方就是指定显示位置的时候我也是写死的,不应该写死,应该重载showPopup()方法,将不同位置都写出来封装好,到时根据不同需求调用不同方法。这个就让大家根据需求自己写好了,这里就不写出来了。


下面是点击评论图标执行的代码:

case R.id.showComments: {
        // 用户点击评论图标
        int animationStyle = R.style.popupAnimation_comments;   //指定PopupWindow显示的内容
        mShowCommentsPopupWindow = new ShowCommentsPopupWindow(context,animationStyle);
        mShowCommentsPopupWindow.showPopup(mCurrentViewHolder.showComments,R.layout.popup_show_comments,225f, 50f);
        final PopupWindow mPopupWindow = mShowCommentsPopupWindow.popWindow;
        View mContentView = mPopupWindow.getContentView();
        // 点赞
        mContentView.findViewById(R.id.imgPraise).setOnClickListener(
                                new OnClickListener() {
                                        @Override
                                        public void onClick(View v) {
                                                // 点赞的逻辑

                                                //并且让PopupWindow隐藏
                                                mPopupWindow.dismiss();

                                        }
                                });
        // 评论
        mContentView.findViewById(R.id.imgReply).setOnClickListener(

                                new OnClickListener() {
                                        @Override
                                        public void onClick(View v) {

                                        // 评论的逻辑

                                        //并且让PopupWindow隐藏
                                        mPopupWindow.dismiss();

                                        }
                                });
        // 分享
        mContentView.findViewById(R.id.llShare).setOnClickListener(
                                new OnClickListener() {
                                        @Override
                                        public void onClick(View v) {

                                                // 分享的逻辑

                                                //并且让PopupWindow隐藏
                                                mPopupWindow.dismiss();

                                        }
                                });
        }
        break;


0 0
原创粉丝点击