PopupWindow 这个类用来实现一个弹出框,可以使用任意布局的 View 作为其内容,这个弹出框是悬浮在当前 activity 之上的。

效果图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HaX5p9CD-1575526739000)(https://img-my.csdn.net/uploads/201706/15/1497505682_8071.gif-thumb.jpg)]

1,向下弹出用到了 RecyclerView 所以我们在 app 文件夹下的 build.gradle 添加:

compile 'com.android.support:recyclerview-v7:25.2.0'compile 'com.zhy:base-rvadapter:3.0.3'

2,封装一个通用的 CommonPopupWindow.java

package com.gyq.popupwindowtest.pop;import android.content.Context;import android.view.View;import android.widget.PopupWindow;import com.gyq.popupwindowtest.PopupController;import com.gyq.popupwindowtest.utils.CommonUtil;/** * Created by gyq on 2017/6/15 09:53 */public class CommonPopupWindow extends PopupWindow {    private PopupController controller;    @Override    public int getWidth() {        return controller.mPopupView.getMeasuredWidth();    }    @Override    public int getHeight() {        return controller.mPopupView.getMeasuredHeight();    }    public interface ViewInterface {        void getChildView(View view, int layoutResId);    }    private CommonPopupWindow(Context context) {        controller = new PopupController(context, this);    }    @Override    public void dismiss() {        super.dismiss();        controller.setBackGroundLevel(1.0f);    }    public static class Builder {        private final PopupController.PopupParams params;        private ViewInterface listener;        public Builder(Context context) {            params = new PopupController.PopupParams(context);        }        /**         * @param layoutResId 设置PopupWindow 布局ID         * @return Builder         */        public Builder setView(int layoutResId) {            params.mView = null;            params.layoutResId = layoutResId;            return this;        }        /**         * @param view 设置PopupWindow布局         * @return Builder         */        public Builder setView(View view) {            params.mView = view;            params.layoutResId = 0;            return this;        }        /**         * 设置子View         *         * @param listener ViewInterface         * @return Builder         */        public Builder setViewOnclickListener(ViewInterface listener) {            this.listener = listener;            return this;        }        /**         * 设置宽度和高度 如果不设置 默认是wrap_content         *         * @param width 宽         * @return Builder         */        public Builder setWidthAndHeight(int width, int height) {            params.mWidth = width;            params.mHeight = height;            return this;        }        /**         * 设置背景灰色程度         *         * @param level 0.0f-1.0f         * @return Builder         */        public Builder setBackGroundLevel(float level) {            params.isShowBg = true;            params.bg_level = level;            return this;        }        /**         * 是否可点击Outside消失         *         * @param touchable 是否可点击         * @return Builder         */        public Builder setOutsideTouchable(boolean touchable) {            params.isTouchable = touchable;            return this;        }        /**         * 设置动画         *         * @return Builder         */        public Builder setAnimationStyle(int animationStyle) {            params.isShowAnim = true;            params.animationStyle = animationStyle;            return this;        }        public CommonPopupWindow create() {            final CommonPopupWindow popupWindow = new CommonPopupWindow(params.mContext);            params.apply(popupWindow.controller);            if (listener != null && params.layoutResId != 0) {                listener.getChildView(popupWindow.controller.mPopupView, params.layoutResId);            }            CommonUtil.measureWidthAndHeight(popupWindow.controller.mPopupView);            return popupWindow;        }    }}

其中,用到的 PopupController.java

package com.gyq.popupwindowtest;import android.app.Activity;import android.content.Context;import android.graphics.drawable.ColorDrawable;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.view.Window;import android.view.WindowManager;import android.widget.PopupWindow;/** * Created by gyq on 2017/6/15 09:52 */public class PopupController {    private int layoutResId;//布局id    private Context context;    private PopupWindow popupWindow;    public View mPopupView;//弹窗布局View    private View mView;    private Window mWindow;    public PopupController(Context context, PopupWindow popupWindow) {        this.context = context;        this.popupWindow = popupWindow;    }    public void setView(int layoutResId) {        mView = null;        this.layoutResId = layoutResId;        installContent();    }    public void setView(View view) {        mView = view;        this.layoutResId = 0;        installContent();    }    private void installContent() {        if (layoutResId != 0) {            mPopupView = LayoutInflater.from(context).inflate(layoutResId, null);        } else if (mView != null) {            mPopupView = mView;        }        popupWindow.setContentView(mPopupView);    }    /**     * 设置宽度     *     * @param width  宽     * @param height 高     */    private void setWidthAndHeight(int width, int height) {        if (width == 0 || height == 0) {            //如果没设置宽高,默认是WRAP_CONTENT            popupWindow.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);            popupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);        } else {            popupWindow.setWidth(width);            popupWindow.setHeight(height);        }    }    /**     * 设置背景灰色程度     *     * @param level 0.0f-1.0f     */    public void setBackGroundLevel(float level) {        mWindow = ((Activity) context).getWindow();        WindowManager.LayoutParams params = mWindow.getAttributes();        params.alpha = level;        mWindow.setAttributes(params);    }    /**     * 设置动画     */    private void setAnimationStyle(int animationStyle) {        popupWindow.setAnimationStyle(animationStyle);    }    /**     * 设置Outside是否可点击     *     * @param touchable 是否可点击     */    private void setOutsideTouchable(boolean touchable) {        popupWindow.setBackgroundDrawable(new ColorDrawable(0x00000000));//设置透明背景        popupWindow.setOutsideTouchable(touchable);//设置outside可点击        popupWindow.setFocusable(touchable);    }    public static class PopupParams {        public int layoutResId;//布局id        public Context mContext;        public int mWidth, mHeight;//弹窗的宽和高        public boolean isShowBg, isShowAnim;        public float bg_level;//屏幕背景灰色程度        public int animationStyle;//动画Id        public View mView;        public boolean isTouchable = true;        public PopupParams(Context mContext) {            this.mContext = mContext;        }        public void apply(PopupController controller) {            if (mView != null) {                controller.setView(mView);            } else if (layoutResId != 0) {                controller.setView(layoutResId);            } else {                throw new IllegalArgumentException("PopupView's contentView is null");            }            controller.setWidthAndHeight(mWidth, mHeight);            controller.setOutsideTouchable(isTouchable);//设置outside可点击            if (isShowBg) {                //设置背景                controller.setBackGroundLevel(bg_level);            }            if (isShowAnim) {                controller.setAnimationStyle(animationStyle);            }        }    }}

3,给 RecyclerView 的 item 设置间距 SpacesItemDecoration.java

package com.gyq.popupwindowtest.pop;import android.graphics.Rect;import android.support.v7.widget.RecyclerView;import android.view.View;/** * Created by gyq on 2017/6/15 13:34 */public class SpacesItemDecoration extends RecyclerView.ItemDecoration {    private int space;    public SpacesItemDecoration(int space) {        this.space = space;    }    @Override    public void getItemOffsets(Rect outRect, View view,                               RecyclerView parent, RecyclerView.State state) {        outRect.left = space;        outRect.right = space;        outRect.bottom = space;        // Add top margin only for the first item to avoid double space between items        if (parent.getChildPosition(view) == 0)            outRect.top = space;    }}

4,在 MainActivity.java 中使用:

package com.gyq.popupwindowtest;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.support.v7.widget.GridLayoutManager;import android.support.v7.widget.RecyclerView;import android.view.Gravity;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.widget.Button;import android.widget.TextView;import android.widget.Toast;import com.gyq.popupwindowtest.pop.CommonPopupWindow;import com.gyq.popupwindowtest.pop.SpacesItemDecoration;import com.gyq.popupwindowtest.utils.CommonUtil;import com.zhy.adapter.recyclerview.CommonAdapter;import com.zhy.adapter.recyclerview.MultiItemTypeAdapter;import com.zhy.adapter.recyclerview.base.ViewHolder;import java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity {    private Button mCenter,mTop,mBottom,mLeft,mRight;    private CommonPopupWindow popupWindow;    private CommonAdapter<String> mAdapter;    private List<String> mDatas = new ArrayList<>();    private int spacingInPixels = 18;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initViews();        initListener();        loadDatas();    }    private void loadDatas() {        for (int i = 0;i < 10;i++) {            mDatas.add("王者荣耀");        }    }    private void initListener() {        //仿微信修改头像弹出pop        mCenter.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                if (popupWindow != null && popupWindow.isShowing()) {                    return;                }                View upView = LayoutInflater.from(MainActivity.this).inflate(R.layout.popup_up, null);                CommonUtil.measureWidthAndHeight(upView);                popupWindow = new CommonPopupWindow.Builder(MainActivity.this)                        .setView(R.layout.popup_up)                        .setWidthAndHeight(ViewGroup.LayoutParams.MATCH_PARENT,upView.getMeasuredHeight())                        .setBackGroundLevel(0.5f)//取值范围0.0f-1.0f 值越小越暗                        .setAnimationStyle(R.style.AnimUp)                        .setViewOnclickListener(new CommonPopupWindow.ViewInterface() {                            @Override                            public void getChildView(View view, int layoutResId) {                                Button btn_take_photo = (Button) view.findViewById(R.id.btn_take_photo);                                Button btn_select_photo = (Button) view.findViewById(R.id.btn_select_photo);                                Button btn_cancel = (Button) view.findViewById(R.id.btn_cancel);                                btn_take_photo.setOnClickListener(new View.OnClickListener() {                                    @Override                                    public void onClick(View v) {                                        toast("拍照");                                        if (popupWindow != null) {                                            popupWindow.dismiss();                                        }                                    }                                });                                btn_select_photo.setOnClickListener(new View.OnClickListener() {                                    @Override                                    public void onClick(View v) {                                        toast("相册选取");                                        if (popupWindow != null) {                                            popupWindow.dismiss();                                        }                                    }                                });                                btn_cancel.setOnClickListener(new View.OnClickListener() {                                    @Override                                    public void onClick(View v) {                                        if (popupWindow != null) {                                            popupWindow.dismiss();                                        }                                    }                                });                                view.setOnTouchListener(new View.OnTouchListener() {                                    @Override                                    public boolean onTouch(View v, MotionEvent event) {                                        if (popupWindow != null) {                                            popupWindow.dismiss();                                        }                                        return true;                                    }                                });                            }                        })                        .create();                popupWindow.showAtLocation(mCenter, Gravity.BOTTOM,0,0);            }        });        //向下弹出pop        mTop.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                if (popupWindow != null && popupWindow.isShowing()) {                    return;                }                popupWindow = new CommonPopupWindow.Builder(MainActivity.this)                        .setView(R.layout.popup_down)                        .setWidthAndHeight(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)                        .setAnimationStyle(R.style.AnimDown)                        .setViewOnclickListener(new CommonPopupWindow.ViewInterface() {                            @Override                            public void getChildView(View view, int layoutResId) {                                RecyclerView rv = (RecyclerView)view.findViewById(R.id.recycler_view);                                GridLayoutManager manager = new GridLayoutManager(MainActivity.this,3);                                rv.setLayoutManager(manager);                                rv.addItemDecoration(new SpacesItemDecoration(spacingInPixels));                                mAdapter = new CommonAdapter<String>(MainActivity.this,R.layout.itme_rv_popup,mDatas) {                                    @Override                                    protected void convert(ViewHolder holder, String s, int position) {                                        holder.setText(R.id.tv_item_title,s);                                    }                                };                                mAdapter.setOnItemClickListener(new MultiItemTypeAdapter.OnItemClickListener() {                                    @Override                                    public void onItemClick(View view, RecyclerView.ViewHolder holder, int position) {                                        toast("点击了" + position);                                    }                                    @Override                                    public boolean onItemLongClick(View view, RecyclerView.ViewHolder holder, int position) {                                        return false;                                    }                                });                                rv.setAdapter(mAdapter);                            }                        })                        .setOutsideTouchable(true)                        .create();                popupWindow.showAsDropDown(view);            }        });        //向右弹pop        mRight.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                if (popupWindow != null && popupWindow.isShowing()) return;                popupWindow = new CommonPopupWindow.Builder(MainActivity.this)                        .setView(R.layout.popup_left_or_right)                        .setWidthAndHeight(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)                        .setAnimationStyle(R.style.AnimHorizontal)                        .setViewOnclickListener(new CommonPopupWindow.ViewInterface() {                            @Override                            public void getChildView(View view, int layoutResId) {                                TextView tv_like = (TextView) view.findViewById(R.id.tv_like);                                TextView tv_hate = (TextView) view.findViewById(R.id.tv_hate);                                tv_like.setOnClickListener(new View.OnClickListener() {                                    @Override                                    public void onClick(View v) {                                        toast("赞一个");                                        popupWindow.dismiss();                                    }                                });                                tv_hate.setOnClickListener(new View.OnClickListener() {                                    @Override                                    public void onClick(View v) {                                        toast("踩一下");                                        popupWindow.dismiss();                                    }                                });                            }                        })                        .create();                popupWindow.showAsDropDown(view, view.getWidth(), -view.getHeight());            }        });        //向左弹pop        mLeft.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                if (popupWindow != null && popupWindow.isShowing()) return;                popupWindow = new CommonPopupWindow.Builder(MainActivity.this)                        .setView(R.layout.popup_left_or_right)                        .setWidthAndHeight(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)                        .setAnimationStyle(R.style.AnimRight)                        .setViewOnclickListener(new CommonPopupWindow.ViewInterface() {                            @Override                            public void getChildView(View view, int layoutResId) {                                TextView tv_like = (TextView) view.findViewById(R.id.tv_like);                                TextView tv_hate = (TextView) view.findViewById(R.id.tv_hate);                                tv_like.setOnClickListener(new View.OnClickListener() {                                    @Override                                    public void onClick(View v) {                                        toast("赞一个");                                        popupWindow.dismiss();                                    }                                });                                tv_hate.setOnClickListener(new View.OnClickListener() {                                    @Override                                    public void onClick(View v) {                                        toast("踩一下");                                        popupWindow.dismiss();                                    }                                });                            }                        })                        .create();                popupWindow.showAsDropDown(view, -popupWindow.getWidth(), -view.getHeight());            }        });        //向上弹pop        mBottom.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                if (popupWindow != null && popupWindow.isShowing()) return;                popupWindow = new CommonPopupWindow.Builder(MainActivity.this)                        .setView(R.layout.popup_left_or_right)                        .setWidthAndHeight(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)                        .setViewOnclickListener(new CommonPopupWindow.ViewInterface() {                            @Override                            public void getChildView(View view, int layoutResId) {                                TextView tv_like = (TextView) view.findViewById(R.id.tv_like);                                TextView tv_hate = (TextView) view.findViewById(R.id.tv_hate);                                tv_like.setOnClickListener(new View.OnClickListener() {                                    @Override                                    public void onClick(View v) {                                        toast("赞一个");                                        popupWindow.dismiss();                                    }                                });                                tv_hate.setOnClickListener(new View.OnClickListener() {                                    @Override                                    public void onClick(View v) {                                        toast("踩一下");                                        popupWindow.dismiss();                                    }                                });                            }                        })                        .create();                popupWindow.showAsDropDown(view, 0, -(popupWindow.getHeight() + view.getMeasuredHeight()));            }        });    }    private void initViews() {        mCenter = (Button)findViewById(R.id.show_center);        mTop = (Button)findViewById(R.id.show_top);        mBottom = (Button)findViewById(R.id.show_bottom);        mLeft = (Button)findViewById(R.id.show_left);        mRight = (Button)findViewById(R.id.show_right);    }    private void toast(String s) {        Toast.makeText(MainActivity.this,s,Toast.LENGTH_SHORT).show();    }}

其中,用到的工具类 CommonUtil.java

package com.gyq.popupwindowtest.utils;import android.view.View;/** * Created by gyq on 2017/6/15 10:06 */public class CommonUtil {    /**     * 测量View的宽高     *     * @param view View     */    public static void measureWidthAndHeight(View view) {        int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);        int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);        view.measure(w, h);    }}

5,布局文件和用到的动画我会上传到我的资源,请自行前往下载!

更多相关文章

  1. 设置程序[置顶] android(10)_android权限大全
  2. Android中Adapter使用ViewHolder优化
  3. Android(安卓)Studio初次使用genymotion注意几点
  4. Android之多语言设置
  5. android 焦点控制
  6. Android学习笔记(14):相对布局RelativeLayout
  7. Android(安卓)Material Design NavigationView
  8. android新特性: 底部导航栏BottomNavigationView系统库与第三方库
  9. 文章【Android(安卓)的视频编码 H263 MP4V H264】的代码实现

随机推荐

  1. Android—关于通知NotificationManager操
  2. Android(安卓)单例模式
  3. Android组件及UI框架大全
  4. 关于Scroller ,scrollTo,scrollBy
  5. WindowManagerService第一讲之WMS基础知
  6. Android 平板电脑设计
  7. android中定时开关机的实现
  8. 【Android 开发】: Android客户端与服务
  9. [转]暑期大学生博客分享大赛 - 2011 Andr
  10. Android多线程AsyncTask详解