其他分享
首页 > 其他分享> > QMUI中CheckableDialog的菜单项数量小于32的限制的解决方案

QMUI中CheckableDialog的菜单项数量小于32的限制的解决方案

作者:互联网

一、QMUI是什么

QMUI是腾讯的一项UI 解决方案,它包含web、Android、IOS三个版本的方案。

QMUI Android 的设计目的是用于辅助快速搭建一个具备基本设计还原效果的 Android 项目,
同时利用自身提供的丰富控件及兼容处理,
让开发者能专注于业务需求而无需耗费精力在基础代码的设计上。
不管是新项目的创建,或是已有项目的维护,
均可使开发效率和项目质量得到大幅度提升。

具体使用方式,这里不表,自行查看官网API。

QMUI官网

二、问题描述

其中QMUIDialog是个弹窗组件。

提供了一系列常用的对话框,解决了使用系统默认对话框时在不同 Android 版本上的表现不一致的问题。使用不同的 Builder 来构建不同类型的对话框,这些 Builder 都拥有设置 title 和添加底部按钮的功能,不同的 Builder 特有的作用如下:

  1. MessageDialogBuilder: 消息类型的对话框 Builder。通过它可以生成一个带标题、文本消息、按钮的对话框。
  2. ConfirmMessageDialogBuilder: 带 Checkbox 的消息确认框 Builder。
  3. EditTextDialogBuilder: 带输入框的对话框 Builder。
  4. MenuDialogBuilder: 菜单对话框 Builder。
  5. CheckableDialogBuilder: 单选类型的对话框 Builder。
  6. MultiCheckableDialogBuilder: 多选类型的对话框 Builder。
  7. CustomDialogBuilder: 自定义对话框内容区域的 Builder。
  8. AutoResizeDialogBuilder: 随键盘升降自动调整 Dialog 高度的 Builder

今天我们遇到的问题就是使用MultiCheckableDialogBuilder时遇到的,按官方例子使用时完全没有问题

watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=

但是当我们的选项多于32项时,就会抛出错误提示

there are more than 32 items, please use LiseView to improve performance!!

 

三、解题思路

QMUI作者本意可能是dialog组件不适合太多的选项,但是实际应用中怎么可能就限制死了只有32个选项。

既然有错误提示,那就肯定是源码中有限制,尝试找找看源码怎么写的。

然后在aar包中找到了QMUIDialog文件

watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=

其中有如下方法addItem做了限制

        @Override
        public MultiCheckableDialogBuilder addItem(QMUIDialogMenuItemView itemView, OnClickListener listener) {
            if(mMenuItemViewsFactoryList.size() >= 32){
                throw new RuntimeException("there are more than 32 items, please use LiseView to improve performance!!");
            }
            return super.addItem(itemView, listener);
        }

        @Override
        public MultiCheckableDialogBuilder addItem(ItemViewFactory itemViewFactory, OnClickListener listener) {
            if(mMenuItemViewsFactoryList.size() >= 32){
                throw new RuntimeException("there are more than 32 items, please use LiseView to improve performance!!");
            }
            return super.addItem(itemViewFactory, listener);
        }

 

四、解决方案

既然找到了问题所在,那就有对应办法了。打算重写这两个方法。

新建了MyQMUIDialog继承QMUIDialog,但是因为我们只要修改MultiCheckableDialogBuilder,所以只重写了MultiCheckableDialogBuilder。

然后调用的时候用到MultiCheckableDialogBuilder的地方就用MyQMUIDialog中的MultiCheckableDialogBuilder调用。

import android.content.Context;
import android.view.ViewGroup;

import com.qmuiteam.qmui.widget.dialog.QMUIDialog;
import com.qmuiteam.qmui.widget.dialog.QMUIDialogMenuItemView;

import java.util.ArrayList;

public class MyQMUIDialog extends QMUIDialog {

    public MyQMUIDialog(Context context) {
        super(context);
    }

    public MyQMUIDialog(Context context, int styleRes) {
        super(context, styleRes);
    }

    /**
     * 多选类型的对话框 Builder
     */
    public static class MultiCheckableDialogBuilder extends MenuBaseDialogBuilder<MyQMUIDialog.MultiCheckableDialogBuilder> {

        /**
         * 该 int 的每一位标识菜单的每一项是否被选中 (1为选中,0位不选中)
         */
        private int mCheckedItems;

        public MultiCheckableDialogBuilder(Context context) {
            super(context);
        }

        /**
         * 设置被选中的菜单项的下标
         *
         * @param checkedItems <b>注意: 该 int 参数的每一位标识菜单项的每一项是否被选中</b>
         *                     <p>如 20 表示选中下标为 1、3 的菜单项, 因为 (2<<1) + (2<<3) = 20</p>
         */
        public MyQMUIDialog.MultiCheckableDialogBuilder setCheckedItems(int checkedItems) {
            mCheckedItems = checkedItems;
            return this;
        }

        /**
         * 设置被选中的菜单项的下标
         *
         * @param checkedIndexes 被选中的菜单项的下标组成的数组,如 [1,3] 表示选中下标为 1、3 的菜单项
         */
        public MyQMUIDialog.MultiCheckableDialogBuilder setCheckedItems(int[] checkedIndexes) {
            int checkedItemRecord = 0;
            if (checkedIndexes != null && checkedIndexes.length > 0) {
                for (int checkedIndexe : checkedIndexes) {
                    checkedItemRecord += 2 << (checkedIndexe);
                }
            }
            return setCheckedItems(checkedItemRecord);
        }

        /**
         * 添加菜单项
         *
         * @param items    所有菜单项的文字
         * @param listener 菜单项的点击事件,可以在点击事件里调用 {@link #setCheckedItems(int[])}} 来设置选中某些菜单项
         */
        public MyQMUIDialog.MultiCheckableDialogBuilder addItems(CharSequence[] items, OnClickListener listener) {
            for (final CharSequence item : items) {
                addItem(new ItemViewFactory() {
                    @Override
                    public QMUIDialogMenuItemView createItemView(Context context) {
                        return new QMUIDialogMenuItemView.CheckItemView(context, true, item);
                    }
                }, listener);
            }
            return this;
        }

        @Override
        public MyQMUIDialog.MultiCheckableDialogBuilder addItem(QMUIDialogMenuItemView itemView, OnClickListener listener) {
//            if(mMenuItemViewsFactoryList.size() >= 32){
//                throw new RuntimeException("there are more than 32 items, please use LiseView to improve performance!!");
//            }
            return super.addItem(itemView, listener);
        }

        @Override
        public MyQMUIDialog.MultiCheckableDialogBuilder addItem(ItemViewFactory itemViewFactory, OnClickListener listener) {
//            if(mMenuItemViewsFactoryList.size() >= 32){
//                throw new RuntimeException("there are more than 32 items, please use LiseView to improve performance!!");
//            }
            return super.addItem(itemViewFactory, listener);
        }

        @Override
        protected void onCreateContent(QMUIDialog dialog, ViewGroup parent, Context context) {
            super.onCreateContent(dialog, parent, context);
            for (int i = 0; i < mMenuItemViews.size(); i++) {
                QMUIDialogMenuItemView itemView = mMenuItemViews.get(i);
                int v = 2 << i;
                itemView.setChecked((v & mCheckedItems) == v);
            }
        }

        @Override
        protected void onItemClick(int index) {
            QMUIDialogMenuItemView itemView = mMenuItemViews.get(index);
            itemView.setChecked(!itemView.isChecked());
        }

        /**
         * @return 被选中的菜单项的下标 <b>注意: 如果选中的是1,3项(以0开始),因为 (2<<1) + (2<<3) = 20</b>
         */
        public int getCheckedItemRecord() {
            int output = 0;
            int length = mMenuItemViews.size();

            for (int i = 0; i < length; i++) {
                QMUIDialogMenuItemView itemView = mMenuItemViews.get(i);
                if (itemView.isChecked()) {
                    output += 2 << itemView.getMenuIndex();
                }
            }
            mCheckedItems = output;
            return output;
        }

        /**
         * @return 被选中的菜单项的下标数组。如果选中的是1,3项(以0开始),则返回[1,3]
         */
        public int[] getCheckedItemIndexes() {
            ArrayList<Integer> array = new ArrayList<>();
            int length = mMenuItemViews.size();

            for (int i = 0; i < length; i++) {
                QMUIDialogMenuItemView itemView = mMenuItemViews.get(i);
                if (itemView.isChecked()) {
                    array.add(itemView.getMenuIndex());
                }
            }
            int[] output = new int[array.size()];
            for (int i = 0; i < array.size(); i++) {
                output[i] = array.get(i);
            }
            return output;
        }

        protected boolean existCheckedItem() {
            return getCheckedItemRecord() <= 0;
        }
    }
}

调用方式如下:

        final MyQMUIDialog.MultiCheckableDialogBuilder builder = new MyQMUIDialog.MultiCheckableDialogBuilder(getActivity())
                .addItems(names, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                    }
                });
        builder.addAction("取消", new QMUIDialogAction.ActionListener() {
            @Override
            public void onClick(QMUIDialog dialog, int index) {
                dialog.dismiss();
            }
        });
        builder.addAction("提交", new QMUIDialogAction.ActionListener() {
            @Override
            public void onClick(QMUIDialog dialog, int index) {
                //提交处理
                dialog.dismiss();
            }
        });
        builder.create(mCurrentDialogStyle).show();

标签:QMUI,对话框,int,32,Builder,CheckableDialog,MultiCheckableDialogBuilder,public
来源: https://blog.51cto.com/xuepiaoqiyue/2907770