化繁为简之SimplePopupWindow

作者: IT独立开发者 | 来源:发表于2017-08-25 13:37 被阅读130次

    最近项目里总是用到PopupWindow,功能不是很复杂但是写起来很繁琐、代码很乱,所以就自己封装了一个SimplePopupWindow,基于Builder模式。

    功能

    • 可点击空白地方或者返回键使PopupWindow消失
    • 可设置并调节半透明黑色背景,并且PopupWindow消失后背景色自动恢复
    • 不会被软键盘覆盖
    • 可设置是否同时弹出软键盘
    • 可设置进出动画

    一个简单带动画的PopupWindow弹出

    image

    只需四行代码加一个接口回调

    SimplePopupWindow.with(MainActivity.this)
        .setView(R.layout.popup_window_main)  //设置你的视图资源文件
        .setAnimationStyle(R.style.anim_simple_popup_window)  //设置你的动画资源文件
        .show(new SimplePopupWindow.Callback() {
        @Override
        public void getView(View view, PopupWindow popupWindow) {
            //view是你资源文件生成的视图
        
        }
    });
    

    NOTE:后面放出动画的资源文件

    带半透明灰色背景

    image
    SimplePopupWindow.with(MainActivity.this)
        .setView(R.layout.popup_window_main)
        .setBackgroundAlpha(0.4f)  //设置你的背景透明度
        .show(new SimplePopupWindow.Callback() {
        @Override
        public void getView(View view, PopupWindow popupWindow) {
        
        }
    });
    

    API文档

    方法 用途
    with(Activity activity) 初始化
    show(Callback callback) 弹出PopupWindow
    setView(int ResId) 设置视图的资源文件
    setLocation(int Lacation) 设置弹出位置
    setBackgroundAlpha(float bgAlpha) 设置黑色背景透明度
    setAnimationStyle(int animationStyle) 设置动画的资源文件
    setAutoPopupInput(boolean isShowInput) 设置是否自动弹出软键盘

    Note:

    • 不要在Activity的onCreate()方法中直接show(),因为此时Activity的视图开没有绘制完成。
    • 一定要在show()之前调用setView()。
    • layout布局文件要设置固定高度或wrap_content

    SimplePopupWindow代码

    //直接新建SimplePopupWindow类拷贝过去
    public class SimplePopupWindow {
    private Activity mActivity;
    private View mView;
    private boolean mIsShowInput;
    private int animationStyle;
    private int LOCATION = -1;
    
    
    public static SimplePopupWindow with(Activity activity) {
        return new SimplePopupWindow(activity);
    }
    
    
    public SimplePopupWindow(Activity activity) {
        mActivity = activity;
        animationStyle = -1;
    }
    
    
    //设置弹出位置,默认底部弹出
    public void setLocation(int Lacation){
        LOCATION = Lacation;
    }
    
    
    //视图资源,必须设置
    public SimplePopupWindow setView(int ResId) {
        mView = LayoutInflater.from(mActivity).inflate(ResId, null);
        return this;
    }
    
    
    //弹出PopupWindow
    public void show(Callback callback) {
        if (mView == null){
            Toast.makeText(mActivity,"请设置View", Toast.LENGTH_SHORT).show();
            return;
        }
    
        PopupWindow window = new PopupWindow(mView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, true);
    
        if (animationStyle != -1)  //如果设置了动画,则启用动画
            window.setAnimationStyle(animationStyle);
    
        window.setBackgroundDrawable(new ColorDrawable());
    
        window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);  //不会被软键盘覆盖
    
        window.setOnDismissListener(new PopupWindow.OnDismissListener() { //弹窗消失时恢复背景色
            @Override
            public void onDismiss() {
                setBackgroundAlpha(1f);
            }
        });
    
        callback.getView(mView,window);
    
        if (LOCATION != -1)
            window.showAtLocation(mActivity.getWindow().getDecorView().findViewById(android.R.id.content), LOCATION, 0, 0);
        else
            window.showAtLocation(mActivity.getWindow().getDecorView().findViewById(android.R.id.content), Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 0);
        
        showInPut();
    }
    
    
    //设置黑色半透明背景,建议设置0.4f,默认不设置
    public SimplePopupWindow setBackgroundAlpha(float bgAlpha) {
        WindowManager.LayoutParams lp = mActivity.getWindow().getAttributes();
        lp.alpha = bgAlpha;
        if (bgAlpha == 1) {
            mActivity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);//不移除该Flag的话,在有视频的页面上的视频会出现黑屏的bug
        } else {
            mActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);//此行代码主要是解决在华为手机上半透明效果无效的bug
        }
        mActivity.getWindow().setAttributes(lp);
        return this;
    }
    
    
    //设置是否自动弹出软键盘,默认为否
    public SimplePopupWindow setAutoPopupInput(boolean isShowInput) {
        mIsShowInput = isShowInput;
        return this;
    }
    
    
    //设置进出动画
    public SimplePopupWindow setAnimationStyle(int animationStyle){
        this.animationStyle = animationStyle;
        return this;
    }
    
    
    //显示软键盘
    private void showInPut(){
        if (mIsShowInput){
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    InputMethodManager imm = (InputMethodManager)mActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
                    imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
                }
            }, 0);
        }
    }
    
    
    //接口回调
    public interface Callback {
        void getView(View view, PopupWindow popupWindow);
      }
    }
    

    动画资源文件

    transition/out.xml (新建transition或anim目录)

     <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android" >
        <translate
            android:duration="250"  
            android:fromYDelta="0.0"
            android:toYDelta="100%" />
    </set>
    

    transition/in.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android" >
        <translate
            android:duration="250"
            android:fromYDelta="100.0%"
            android:toYDelta="0.0" />
    </set>
    

    values/styles.xml

    <style name="anim_simple_popup_window">
        <item name="android:windowEnterAnimation">@transition/in</item>
        <item name="android:windowExitAnimation">@transition/out</item>
    </style>
    

    相关文章

      网友评论

      • Kcwind:每次show都要new一个PopupWindow,是不是不太好
      • Blazer:popupwindow里面view设置监听呢?

      本文标题:化繁为简之SimplePopupWindow

      本文链接:https://www.haomeiwen.com/subject/dzyudxtx.html