对PopupWindow常用API的简单封装,几行代码就搞定PopupWindow弹窗,使用Builder模式,链式调用,像使用AlertDialog 一样

来源:互联网 发布:java工程师面试题 编辑:程序博客网 时间:2024/05/21 21:33

示例效果图:

这是他的GitHub挺不错的

原方法在最下面,就只有一个类,很简洁很方便!

效果图

使用方法

更新1:背景变暗配置示例:

   //创建并显示popWindow mCustomPopWindow= new CustomPopWindow.PopupWindowBuilder(this)                .setView(contentView)                .enableBackgroundDark(true) //弹出popWindow时,背景是否变暗                .setBgDarkAlpha(0.7f) // 控制亮度                .create()                .showAsDropDown(mButton5,0,20);

更新2:显示消失动画配置:

 CustomPopWindow popWindow = new CustomPopWindow.PopupWindowBuilder(this)                .setView(R.layout.pop_layout1)                .setFocusable(true)                .setOutsideTouchable(true)                .setAnimationStyle(R.style.CustomPopWindowStyle) // 添加自定义显示和消失动画                .create()                .showAsDropDown(mButton1,0,10);

更新3:点击PopupWindow以外区域不让关闭(默认DisMiss):

 mPopWindow = new CustomPopWindow.PopupWindowBuilder(this)                .setView(view)                .enableOutsideTouchableDissmiss(false)// 设置点击PopupWindow之外的地方,popWindow不关闭,如果不设置这个属性或者为true,则关闭                .create();        mPopWindow.showAsDropDown(mButton7,0,10);

1,简便写法

CustomPopWindow popWindow = new CustomPopWindow.PopupWindowBuilder(this)                .setView(R.layout.pop_layout1)//显示的布局,还可以通过设置一个View           //     .size(600,400) //设置显示的大小,不设置就默认包裹内容                .setFocusable(true)//是否获取焦点,默认为ture                .setOutsideTouchable(true)//是否PopupWindow 以外触摸dissmiss                .create()//创建PopupWindow                .showAsDropDown(mButton1,0,10);//显示PopupWindow

以上就是弹出一个简单的PopupWindow,是不是看起来很优雅和简单,还可以简单一点:

CustomPopWindow popWindow = new CustomPopWindow.PopupWindowBuilder(this)                .setView(R.layout.pop_layout1)//显示的布局                .create()//创建PopupWindow                .showAsDropDown(mButton1,0,10);//显示PopupWindow

如果是一个简单的只展示文案的弹窗,就可以只设置一个View,就可以了,很简单吧!!!

2,展示一个PopupWindow 弹窗菜单(像手机QQ,微信的顶部菜单)

View contentView = LayoutInflater.from(this).inflate(R.layout.pop_menu,null);        //处理popWindow 显示内容        handleLogic(contentView);        //创建并显示popWindow        mCustomPopWindow= new CustomPopWindow.PopupWindowBuilder(this)                .setView(contentView)                .create()                .showAsDropDown(mButton3,0,20);

如果PopupWindow 展示的内容需要在程序代码中设置或者响应点击事件等,可以现获取到这个View,然后处理一些显示和点击事件逻辑,再交给CustomPopWindow 创建显示。比如响应菜单点击事件的逻辑处理:

 /**     * 处理弹出显示内容、点击事件等逻辑     * @param contentView     */    private void handleLogic(View contentView){        View.OnClickListener listener = new View.OnClickListener() {            @Override            public void onClick(View v) {                if(mCustomPopWindow!=null){                    mCustomPopWindow.dissmiss();                }                String showContent = "";                switch (v.getId()){                    case R.id.menu1:                        showContent = "点击 Item菜单1";                        break;                    case R.id.menu2:                        showContent = "点击 Item菜单2";                        break;                    case R.id.menu3:                        showContent = "点击 Item菜单3";                        break;                    case R.id.menu4:                        showContent = "点击 Item菜单4";                        break;                    case R.id.menu5:                        showContent = "点击 Item菜单5" ;                        break;                }                Toast.makeText(MainActivity.this,showContent,Toast.LENGTH_SHORT).show();            }        };        contentView.findViewById(R.id.menu1).setOnClickListener(listener);        contentView.findViewById(R.id.menu2).setOnClickListener(listener);        contentView.findViewById(R.id.menu3).setOnClickListener(listener);        contentView.findViewById(R.id.menu4).setOnClickListener(listener);        contentView.findViewById(R.id.menu5).setOnClickListener(listener);    }}

3,展示一个ListView,其实跟上面是一样的,这里贴一下实例代码:

private void showPopListView(){        View contentView = LayoutInflater.from(this).inflate(R.layout.pop_list,null);        //处理popWindow 显示内容        handleListView(contentView);        //创建并显示popWindow        mListPopWindow= new CustomPopWindow.PopupWindowBuilder(this)                .setView(contentView)                .size(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT)//显示大小                .create()                .showAsDropDown(mButton4,0,20);    }    private void handleListView(View contentView){        RecyclerView recyclerView = (RecyclerView) contentView.findViewById(R.id.recyclerView);        LinearLayoutManager manager = new LinearLayoutManager(this);        manager.setOrientation(LinearLayoutManager.VERTICAL);        recyclerView.setLayoutManager(manager);        MyAdapter adapter = new MyAdapter();        adapter.setData(mockData());        recyclerView.setAdapter(adapter);        adapter.notifyDataSetChanged();    }

他的依赖里面只有这一个类,很不错,很有想法!【可以直接用,也可以看看他的GitHub介绍】

package com.example.zhouwei.library;import android.app.Activity;import android.content.Context;import android.graphics.Color;import android.graphics.drawable.ColorDrawable;import android.os.Build;import android.support.annotation.RequiresApi;import android.util.Log;import android.view.KeyEvent;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.view.Window;import android.view.WindowManager;import android.widget.PopupWindow;/** * * 自定义PopWindow类,封装了PopWindow的一些常用属性,用Builder模式支持链式调用 * Created by zhouwei on 16/11/28. */public class CustomPopWindow implements PopupWindow.OnDismissListener{    private static final String TAG = "CustomPopWindow";    private static final float DEFAULT_ALPHA = 0.7f;    private Context mContext;    private int mWidth;    private int mHeight;    private boolean mIsFocusable = true;    private boolean mIsOutside = true;    private int mResLayoutId = -1;    private View mContentView;    private PopupWindow mPopupWindow;    private int mAnimationStyle = -1;    private boolean mClippEnable = true;//default is true    private boolean mIgnoreCheekPress = false;    private int mInputMode = -1;    private PopupWindow.OnDismissListener mOnDismissListener;    private int mSoftInputMode = -1;    private boolean mTouchable = true;//default is ture    private View.OnTouchListener mOnTouchListener;    private Window mWindow;//当前Activity 的窗口    /**     * 弹出PopWindow 背景是否变暗,默认不会变暗。     */    private boolean mIsBackgroundDark = false;    private float mBackgroundDrakValue = 0;// 背景变暗的值,0 - 1    /**     * 设置是否允许点击 PopupWindow之外的地方,关闭PopupWindow     */    private boolean enableOutsideTouchDisMiss = true;// 默认点击pop之外的地方可以关闭    private CustomPopWindow(Context context){        mContext = context;    }    public int getWidth() {        return mWidth;    }    public int getHeight() {        return mHeight;    }    /**     *     * @param anchor     * @param xOff     * @param yOff     * @return     */    public CustomPopWindow showAsDropDown(View anchor, int xOff, int yOff){        if(mPopupWindow!=null){            mPopupWindow.showAsDropDown(anchor,xOff,yOff);        }        return this;    }    public CustomPopWindow showAsDropDown(View anchor){        if(mPopupWindow!=null){            mPopupWindow.showAsDropDown(anchor);        }        return this;    }    @RequiresApi(api = Build.VERSION_CODES.KITKAT)    public CustomPopWindow showAsDropDown(View anchor, int xOff, int yOff, int gravity){        if(mPopupWindow!=null){            mPopupWindow.showAsDropDown(anchor,xOff,yOff,gravity);        }        return this;    }    /**     * 相对于父控件的位置(通过设置Gravity.CENTER,下方Gravity.BOTTOM等 ),可以设置具体位置坐标     * @param parent 父控件     * @param gravity     * @param x the popup's x location offset     * @param y the popup's y location offset     * @return     */    public CustomPopWindow showAtLocation(View parent, int gravity, int x, int y){        if(mPopupWindow!=null){            mPopupWindow.showAtLocation(parent,gravity,x,y);        }        return this;    }    /**     * 添加一些属性设置     * @param popupWindow     */    private void apply(PopupWindow popupWindow){        popupWindow.setClippingEnabled(mClippEnable);        if(mIgnoreCheekPress){            popupWindow.setIgnoreCheekPress();        }        if(mInputMode!=-1){            popupWindow.setInputMethodMode(mInputMode);        }        if(mSoftInputMode!=-1){            popupWindow.setSoftInputMode(mSoftInputMode);        }        if(mOnDismissListener!=null){            popupWindow.setOnDismissListener(mOnDismissListener);        }        if(mOnTouchListener!=null){            popupWindow.setTouchInterceptor(mOnTouchListener);        }        popupWindow.setTouchable(mTouchable);    }    private PopupWindow build(){        if(mContentView == null){            mContentView = LayoutInflater.from(mContext).inflate(mResLayoutId,null);        }        // 2017.3.17 add        // 获取当前Activity的window        Activity activity = (Activity) mContentView.getContext();        if(activity!=null && mIsBackgroundDark){            //如果设置的值在0 - 1的范围内,则用设置的值,否则用默认值            final  float alpha = (mBackgroundDrakValue > 0 && mBackgroundDrakValue < 1) ? mBackgroundDrakValue : DEFAULT_ALPHA;            mWindow = activity.getWindow();            WindowManager.LayoutParams params = mWindow.getAttributes();            params.alpha = alpha;            mWindow.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);            mWindow.setAttributes(params);        }        if(mWidth != 0 && mHeight!=0 ){            mPopupWindow = new PopupWindow(mContentView,mWidth,mHeight);        }else{            mPopupWindow = new PopupWindow(mContentView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);        }        if(mAnimationStyle!=-1){            mPopupWindow.setAnimationStyle(mAnimationStyle);        }        apply(mPopupWindow);//设置一些属性        if(mWidth == 0 || mHeight == 0){            mPopupWindow.getContentView().measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);            //如果外面没有设置宽高的情况下,计算宽高并赋值            mWidth = mPopupWindow.getContentView().getMeasuredWidth();            mHeight = mPopupWindow.getContentView().getMeasuredHeight();        }        // 添加dissmiss 监听        mPopupWindow.setOnDismissListener(this);        //2017.6.27 add:fix 设置  setOutsideTouchable(false)点击外部取消的bug.        // 判断是否点击PopupWindow之外的地方关闭 popWindow        if(!enableOutsideTouchDisMiss){            //注意这三个属性必须同时设置,不然不能disMiss,以下三行代码在Android 4.4 上是可以,然后在Android 6.0以上,下面的三行代码就不起作用了,就得用下面的方法            mPopupWindow.setFocusable(true);            mPopupWindow.setOutsideTouchable(false);            mPopupWindow.setBackgroundDrawable(null);            //注意下面这三个是contentView 不是PopupWindow            mPopupWindow.getContentView().setFocusable(true);            mPopupWindow.getContentView().setFocusableInTouchMode(true);            mPopupWindow.getContentView().setOnKeyListener(new View.OnKeyListener() {                @Override                public boolean onKey(View v, int keyCode, KeyEvent event) {                    if (keyCode == KeyEvent.KEYCODE_BACK) {                        mPopupWindow.dismiss();                        return true;                    }                    return false;                }            });            //在Android 6.0以上 ,只能通过拦截事件来解决            mPopupWindow.setTouchInterceptor(new View.OnTouchListener() {                @Override                public boolean onTouch(View v, MotionEvent event) {                    final int x = (int) event.getX();                    final int y = (int) event.getY();                    if ((event.getAction() == MotionEvent.ACTION_DOWN)                            && ((x < 0) || (x >= mWidth) || (y < 0) || (y >= mHeight))) {                        Log.e(TAG,"out side ");                        Log.e(TAG,"width:"+mPopupWindow.getWidth()+"height:"+mPopupWindow.getHeight()+" x:"+x+" y  :"+y);                        return true;                    } else if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {                        Log.e(TAG,"out side ...");                        return true;                    }                    return false;                }            });        }else{            mPopupWindow.setFocusable(mIsFocusable);            mPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));            mPopupWindow.setOutsideTouchable(mIsOutside);        }        // update        mPopupWindow.update();        return mPopupWindow;    }    @Override    public void onDismiss() {        dissmiss();    }    /**     * 关闭popWindow     */    public void dissmiss(){        if(mOnDismissListener!=null){            mOnDismissListener.onDismiss();        }        //如果设置了背景变暗,那么在dissmiss的时候需要还原        if(mWindow!=null){            WindowManager.LayoutParams params = mWindow.getAttributes();            params.alpha = 1.0f;            mWindow.setAttributes(params);        }        if(mPopupWindow!=null && mPopupWindow.isShowing()){            mPopupWindow.dismiss();        }    }    public PopupWindow getPopupWindow() {        return mPopupWindow;    }    public static class PopupWindowBuilder{        private CustomPopWindow mCustomPopWindow;        public PopupWindowBuilder(Context context){            mCustomPopWindow = new CustomPopWindow(context);        }        public PopupWindowBuilder size(int width,int height){            mCustomPopWindow.mWidth = width;            mCustomPopWindow.mHeight = height;            return this;        }        public PopupWindowBuilder setFocusable(boolean focusable){            mCustomPopWindow.mIsFocusable = focusable;            return this;        }        public PopupWindowBuilder setView(int resLayoutId){            mCustomPopWindow.mResLayoutId = resLayoutId;            mCustomPopWindow.mContentView = null;            return this;        }        public PopupWindowBuilder setView(View view){            mCustomPopWindow.mContentView = view;            mCustomPopWindow.mResLayoutId = -1;            return this;        }        public PopupWindowBuilder setOutsideTouchable(boolean outsideTouchable){            mCustomPopWindow.mIsOutside = outsideTouchable;            return this;        }        /**         * 设置弹窗动画         * @param animationStyle         * @return         */        public PopupWindowBuilder setAnimationStyle(int animationStyle){            mCustomPopWindow.mAnimationStyle = animationStyle;            return this;        }        public PopupWindowBuilder setClippingEnable(boolean enable){            mCustomPopWindow.mClippEnable =enable;            return this;        }        public PopupWindowBuilder setIgnoreCheekPress(boolean ignoreCheekPress){            mCustomPopWindow.mIgnoreCheekPress = ignoreCheekPress;            return this;        }        public PopupWindowBuilder setInputMethodMode(int mode){            mCustomPopWindow.mInputMode = mode;            return this;        }        public PopupWindowBuilder setOnDissmissListener(PopupWindow.OnDismissListener onDissmissListener){            mCustomPopWindow.mOnDismissListener = onDissmissListener;            return this;        }        public PopupWindowBuilder setSoftInputMode(int softInputMode){            mCustomPopWindow.mSoftInputMode = softInputMode;            return this;        }        public PopupWindowBuilder setTouchable(boolean touchable){            mCustomPopWindow.mTouchable = touchable;            return this;        }        public PopupWindowBuilder setTouchIntercepter(View.OnTouchListener touchIntercepter){            mCustomPopWindow.mOnTouchListener = touchIntercepter;            return this;        }        /**         * 设置背景变暗是否可用         * @param isDark         * @return         */        public PopupWindowBuilder enableBackgroundDark(boolean isDark){            mCustomPopWindow.mIsBackgroundDark = isDark;            return this;        }        /**         * 设置背景变暗的值         * @param darkValue         * @return         */        public PopupWindowBuilder setBgDarkAlpha(float darkValue){            mCustomPopWindow.mBackgroundDrakValue = darkValue;            return this;        }        /**         * 设置是否允许点击 PopupWindow之外的地方,关闭PopupWindow         * @param disMiss         * @return         */        public PopupWindowBuilder enableOutsideTouchableDissmiss(boolean disMiss){            mCustomPopWindow.enableOutsideTouchDisMiss = disMiss;            return this;        }        public CustomPopWindow create(){            //构建PopWindow            mCustomPopWindow.build();            return mCustomPopWindow;        }    }}


阅读全文
0 0
原创粉丝点击