Skip to content

5. 常用设置

Jun edited this page Aug 28, 2019 · 36 revisions

设置主色调

默认情况下,XPopup的主色为灰色,主色作用于Button文字,EditText边框和光标,Check文字的颜色上。 主色调只需要设置一次即可,可以放在Application中设置。

XPopup.setPrimaryColor(getResources().getColor(R.color.colorPrimary));

设置全局的动画时长

默认情况下,弹窗的动画时长为360毫秒。你可以通过下面的方法进行修改:

XPopup.setAnimationDuration(200); // 传入的时长最小为0,动画的时长会影响除Drawer弹窗外的所有弹窗

设置弹窗的半透明背景色值

XPopup.setShadowBgColor(xxx);

常用设置

new XPopup.Builder(getContext())
    .hasShadowBg(true) // 是否有半透明的背景,默认为true
    .dismissOnBackPressed(true) // 按返回键是否关闭弹窗,默认为true
    .dismissOnTouchOutside(true) // 点击外部是否关闭弹窗,默认为true
    .autoDismiss(false) // 操作完毕后是否自动关闭弹窗,默认为true;比如点击ConfirmPopup的确认按钮,默认自动关闭;如果为false,则不会关闭
    .autoOpenSoftInput(true) //是否弹窗显示的同时打开输入法,只在包含输入框的弹窗内才有效,默认为false
    .popupAnimation(PopupAnimation.ScaleAlphaFromCenter) // 设置内置的动画
    .customAnimator(null) // 设置自定义的动画器
    .moveUpToKeyboard(false) // 软键盘弹出时,弹窗是否移动到软键盘上面,默认为true
    .popupPosition(PopupPosition.Right)//手动指定弹窗出现在目标的什么位置,对Attach和Drawer类型弹窗生效
    .hasStatusBarShadow(false) //是否有状态栏阴影,目前对Drawer弹窗和FullScreen弹窗生效
    .offsetX(-10) //弹窗在x方向的偏移量
    .offsetY(-10) //弹窗在y方向的偏移量
    .enableDrag(true) //是否启用拖拽,默认为true,目前对Bottom弹窗有用
    .isCenterHorizontal(true)//默认为false,默认情况下Attach弹窗依靠着目标的左边或者右边,如果isCenterHorizontal为true,则与目标水平居中对齐
    .isRequestFocus(false)//默认为true,默认情况下弹窗会抢占焦点,目的是为了响应返回按键按下事件;如果为false,则不抢焦点
    .setPopupCallback(new SimpleCallback() { //设置显示和隐藏的回调
        @Override
        public void onCreated() { 
             // 弹窗内部onCreate执行完调用
        }
        @Override
        public void beforeShow() {
             uper.beforeShow();
             Log.e("tag", "beforeShow,在每次show之前都会执行,可以用来进行多次的数据更新。");
        }
        @Override
        public void onShow() {
            // 完全显示的时候执行
        }
        @Override
        public void onDismiss() {
            // 完全隐藏的时候执行
        }
        //如果你自己想拦截返回按键事件,则重写这个方法,返回true即可
        @Override
        public boolean onBackPressed() {
             ToastUtils.showShort("我拦截的返回按键,按返回键XPopup不会关闭了");
             return true; //默认返回false
        }
    })
    // 设置弹窗的最大宽高,只对Center和Bottom类型弹窗生效。默认情况下,弹窗的布局是自适应的,如果你设置了最大宽高,则弹窗的宽高不会超过你设置的值!
    // 如果你重写了`getMaxWidth()`和`getMaxHeight()`方法,此方法设置的值会被覆盖;
    .maxWidth(300)
    .maxHeight(400)
    // 如果你想要一个全屏的弹窗,有3种方式:
    // 1. 首先布局要都是`match_parent`,然后调用上面的方法设置这个值为window的宽高即可。
    // 2. 可以重写`getMaxWidth()`和`getMaxHeight()`方法,效果是一样的。
    // 3. 可以继承FullScreenPopupView,直接编写布局即可。
    .asXXX() //所有的设置项都要写在asXXX()方法调用之前

数据和状态保存

如果每次显示都new一个,由于每次都是新的弹窗,状态无法保存。可以选择记录下:

    CustomDrawerPopupView drawerPopupView = new CustomDrawerPopupView(getContext());

    //使用弹窗
    new XPopup.Builder(getContext())
                    .popupPosition(PopupPosition.Right)//右边
                    .hasStatusBarShadow(true) //启用状态栏阴影
                    .asCustom(drawerPopupView)
                    .show();

在RecyclerView中长按弹出弹窗,这种场景需要watch一下itemView:

    CommonAdapter adapter = new CommonAdapter<String>(android.R.layout.simple_list_item_1, data) {
        @Override
        protected void bind(@NonNull ViewHolder holder, @NonNull String s, int position) {
            holder.setText(android.R.id.text1, "长按我试试 - " + position);
            //必须要在事件发生之前就watch
            final XPopup.Builder builder = new XPopup.Builder(getContext()).watchView(holder.itemView);
            holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    builder.asAttachList(new String[]{"置顶", "编辑", "删除"}, null,0,10, new OnSelectListener() {
                        @Override
                        public void onSelect(int position, String text) {
                            ToastUtils.showShort(text);
                        }
                    }).show();
                    return true;
                }
            });
        }
    };

最佳实践

我们在项目中经常会点击某个按钮然后关闭弹窗,接着去做一些事。比如:点击一个按钮,关闭弹窗,然后开启一个界面:

    dismiss();
    getContext().startActivity(new Intent(getContext(), DemoActivity.class));

要知道弹窗的关闭是有一个动画过程的,上面的写法会出现弹窗还没有完全关闭,就立即跳页面,界面有一种顿挫感;而且在设备资源不足的时候,还可能造成丢帧。

为了得到最佳体验,您可以等dismiss动画完全结束去执行一些东西,而不是立即就执行。可以这样做:

    dismissWith(new Runnable() {
        @Override
        public void run() {
            getContext().startActivity(new Intent(getContext(), DemoActivity.class));
        }
    });

每个弹窗本身也有onShow()onDismiss()的生命周期回调,可以根据需要使用。