Android天下第一



郑重申明:

首先,我开发经验也才2年,所以,我发布的代码肯定会或多或少有问题,发现Bug了,你们能自己改的那就自己改,不能改的就私聊我或者下面回复都行,反正我是不会修改的,毕竟我很忙,哈哈哈哈。。。开个玩笑,有问题我会尽力修改。

第二,复制粘贴使用我的代码都是可以的,反正我不在乎,我乐于助人。

第三,没有了。

说了这么多“废话”,我还是先来张图,有句话叫“无图言X”,大家都懂得





其实Android自带多选框也是可以的,奈何我们经理说要做得和iOS一样!



好了,废话不多少,上代码了!

/** * @author: Pengxh * @email: 290677893@qq.com * @description: 多选功能对话框 * @date: 2019/12/13 13:13 */public class MultiSelectDialog extends Dialog implements View.OnClickListener {    private static final String TAG = "MultiSelectDialog";    private Context context;    private boolean cancelable;    private onDialogClickListener listener;    private String title;    private List list;    private String positiveBtn;    private String negativeBtn;    private HashSet hashSet = new HashSet<>();//利用HashSet直接去重    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.dialog_mutilselect);        initView();        setCanceledOnTouchOutside(false);//点击外部区域无法取消对话框        this.setCancelable(cancelable);    }    private void initView() {        TextView mDialogTitle = findViewById(R.id.mDialogTitle);        ListView mSelectListView = findViewById(R.id.mSelectListView);        Button mDialogCancel = findViewById(R.id.mDialogCancel);        Button mDialogConfirm = findViewById(R.id.mDialogConfirm);        mDialogCancel.setOnClickListener(this);        mDialogConfirm.setOnClickListener(this);        if (!TextUtils.isEmpty(title)) {            mDialogTitle.setText(title);        }        if (!TextUtils.isEmpty(negativeBtn)) {            mDialogCancel.setText(negativeBtn);        }        if (!TextUtils.isEmpty(positiveBtn)) {            mDialogConfirm.setText(positiveBtn);        }        MultiSelectAdapter adapter = new MultiSelectAdapter(context, list);        mSelectListView.setAdapter(adapter);        Log.d(TAG, "点击之前: " + hashSet);        mSelectListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {            @Override            public void onItemClick(AdapterView> parent, View view, int position, long id) {                MultiSelectAdapter.EquipmentListViewHolder viewHolder = (MultiSelectAdapter.EquipmentListViewHolder) view.getTag();                String equipID = viewHolder.mTextViewID.getText().toString();//获取当前item上面的ID                boolean checked = viewHolder.mCheckBox.isChecked();                if (checked) {                    viewHolder.mCheckBox.setChecked(false);                    hashSet.remove(equipID);                } else {                    viewHolder.mCheckBox.setChecked(true);                    hashSet.add(equipID);                }                Log.d(TAG, "点击之后: " + hashSet);            }        });    }    //.....此处省略无关代码}

简单说下上面代码意思:

a、定义全局变量

b、初始化XML布局文件

c、初始化控件并赋值

哦,差点忘了,有个地方要注意下,选中的数据需要去重,毕竟肯定有用户来回点击同一个多选框!我就直接用HashSet操作了,没有太多花里胡哨的操作。

这三步简简单单,如果看不懂的,亲,这边建议您Ctrl+C然后Ctrl+V呢!

接下里,用到了一个设计模式——建造者模式

这个模式其实很常见,如果想不起来或者不知道这个模式的,你可以想一下,当你写代码需要Dialog时候,创建对象是不是new AlertDialog.Builder()?对的,这个Builder就是建造者模式的典型特点。好了,这个自定义控件也采用这个方式构建:

1、初始化建造者(构造函数)

private MultiSelectDialog(Builder builder) {        super(builder.mContext, R.style.MultiSelectDialog);        this.context = builder.mContext;        this.title = builder.title;        this.list = builder.dataList;        this.positiveBtn = builder.positiveBtn;        this.negativeBtn = builder.negativeBtn;        this.cancelable = builder.cancelable;        this.listener = builder.listener;    }

2、采用静态内部类方式构建Builder

public static class Builder {        private Context mContext;        private String title;//对话框标题        private List dataList;//传入的数据        private String positiveBtn;//确定按钮        private String negativeBtn;//取消按钮        private boolean cancelable;//对话框是否可取消        private onDialogClickListener listener;//按钮监听        public Builder setContext(Context context) {            this.mContext = context;            return this;        }        public Builder setTitle(String title) {            this.title = title;            return this;        }        public Builder setData(List list) {            this.dataList = list;            return this;        }        public Builder setPositiveButton(String name) {            this.positiveBtn = name;            return this;        }        public Builder setNegativeButton(String name) {            this.negativeBtn = name;            return this;        }        public Builder setCancelable(boolean cancelable) {            this.cancelable = cancelable;            return this;        }        public Builder setOnDialogClickListener(onDialogClickListener listener) {            this.listener = listener;            return this;        }        public MultiSelectDialog build() {            return new MultiSelectDialog(this);        }    }

其实逻辑很简单,就是把你传进来的一切参数全部打包,最后给你输出个你要的Dialog对象。打个比方:织布。工人把线放进机器,然后开动机器,不一会机器就给你造出了布匹。其实代码里面也差不多是这意思

最后一步,将用户选择的参数回传到别的页面。需要提供接口去实现

public interface onDialogClickListener {        void onConfirmClick(Dialog dialog, List list);        void onCancelClick(Dialog dialog);    }    @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.mDialogCancel:                if (listener != null) {                    listener.onCancelClick(this);                }                break;            case R.id.mDialogConfirm:                if (listener != null) {                    listener.onConfirmClick(this, new ArrayList<>(hashSet));                }                break;            default:                Log.e(TAG, "onClick: Error view ID");                break;        }    }

好了,自此,这个控件在Java代码方面就OK了。当然,我省略了一些非必要代码,比如我司业务上面的一些实体类,你们要用的话需要根据自己的需求改成自己的实体类。

最后,我好人做到底,把XML也放出来吧。

<?xml version="1.0" encoding="utf-8"?>