PopWindow封装


首先介绍一下使用方法,下面有源码,复制就可以用

更新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();

    }

联系方式1403363118




/** * * 自定义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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值