一、QMUI是什么
QMUI是腾讯的一项UI 解决方案,它包含web、Android、IOS三个版本的方案。
QMUI Android 的设计目的是用于辅助快速搭建一个具备基本设计还原效果的 Android 项目,
同时利用自身提供的丰富控件及兼容处理,
让开发者能专注于业务需求而无需耗费精力在基础代码的设计上。
不管是新项目的创建,或是已有项目的维护,
均可使开发效率和项目质量得到大幅度提升。
具体使用方式,这里不表,自行查看官网API。
二、问题描述
其中QMUIDialog是个弹窗组件。
提供了一系列常用的对话框,解决了使用系统默认对话框时在不同 Android 版本上的表现不一致的问题。使用不同的 Builder 来构建不同类型的对话框,这些 Builder 都拥有设置 title 和添加底部按钮的功能,不同的 Builder 特有的作用如下:
MessageDialogBuilder
: 消息类型的对话框 Builder。通过它可以生成一个带标题、文本消息、按钮的对话框。ConfirmMessageDialogBuilder
: 带 Checkbox 的消息确认框 Builder。EditTextDialogBuilder
: 带输入框的对话框 Builder。MenuDialogBuilder
: 菜单对话框 Builder。CheckableDialogBuilder
: 单选类型的对话框 Builder。MultiCheckableDialogBuilder
: 多选类型的对话框 Builder。CustomDialogBuilder
: 自定义对话框内容区域的 Builder。AutoResizeDialogBuilder
: 随键盘升降自动调整?Dialog
?高度的 Builder今天我们遇到的问题就是使用MultiCheckableDialogBuilder时遇到的,按官方例子使用时完全没有问题
但是当我们的选项多于32项时,就会抛出错误提示
there are more than 32 items, please use LiseView to improve performance!!
?
三、解题思路
QMUI作者本意可能是dialog组件不适合太多的选项,但是实际应用中怎么可能就限制死了只有32个选项。
既然有错误提示,那就肯定是源码中有限制,尝试找找看源码怎么写的。
然后在aar包中找到了QMUIDialog文件
其中有如下方法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中CheckableDialog的菜单项数量小于32的限制的解决方案
原文:https://blog.51cto.com/xuepiaoqiyue/2907770