📜  如何在 Android 中实现 MultiSelect DropDown?(1)

📅  最后修改于: 2023-12-03 15:24:06.570000             🧑  作者: Mango

在 Android 中实现 MultiSelect Dropdown

实现 MultiSelect Dropdown 有多种方法,但最常用的方法是使用 Spinner 和 CheckBox 组合。此方法的好处是易于使用和理解,并且与 Android 设备的 UI 一致。

实现步骤
1. 创建布局文件

创建一个布局文件并添加 Spinner 和 CheckBox 的组合来创建 MultiSelect Dropdown。

<LinearLayout
    android:id="@+id/parent_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <Spinner
        android:id="@+id/dropdown"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <CheckBox
        android:id="@+id/checkBox"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Select All"
        android:checked="false" />

    <LinearLayout
        android:id="@+id/checkBoxLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" />

</LinearLayout>
2. 创建一个 Adapter

创建一个 Adapter,用于为 Spinner 提供数据。

public class MyAdapter extends ArrayAdapter<String> {
    private ArrayList<String> itemList;
    private Context context;

    public MyAdapter(ArrayList<String> itemList, Context context) {
        super(context, R.layout.dropdown_item, itemList);
        this.itemList = itemList;
        this.context = context;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(R.layout.dropdown_item, null);
        TextView tv = (TextView) convertView.findViewById(R.id.textView);
        tv.setText(itemList.get(position));
        return convertView;
    }
}
3. 创建一个 Dialog

创建一个 Dialog,用于显示所有可选择的选项。

public class MultiSelectDialog extends Dialog implements DialogInterface.OnDismissListener {
    private Context context;
    private String[] items;
    private boolean[] checkedItems;
    private boolean checkAll;
    private ArrayList<String> selectedList = new ArrayList<>();
    private ArrayList<CheckBox> checkBoxList = new ArrayList<>();

    public MultiSelectDialog(Context context, String[] items) {
        super(context);
        this.context = context;
        this.items = items;
        this.checkedItems = new boolean[items.length];
        setTitle("Select items");
        init();
    }

    private void init() {
        LinearLayout linearLayout = new LinearLayout(context);
        linearLayout.setOrientation(LinearLayout.VERTICAL);
        for (int i = 0; i < items.length; i++) {
            CheckBox cb = new CheckBox(context);
            cb.setText(items[i]);
            cb.setTextColor(ContextCompat.getColor(context, R.color.black));
            cb.setChecked(checkedItems[i]);
            checkBoxList.add(cb);
            linearLayout.addView(cb);
        }
        Button okButton = new Button(context);
        okButton.setText("OK");
        okButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                for (int i = 0; i < checkBoxList.size(); i++) {
                    if (checkBoxList.get(i).isChecked()) {
                        selectedList.add(checkBoxList.get(i).getText().toString());
                        checkedItems[i] = true;
                    } else {
                        checkedItems[i] = false;
                    }
                }
                dismiss();
            }
        });
        Button cancelButton = new Button(context);
        cancelButton.setText("Cancel");
        cancelButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dismiss();
            }
        });
        if(checkAll) {
            checkAllFunc();
        }
        if(checkedItems!=null && checkedItems.length>0){
            linearLayout.addView(okButton);
            linearLayout.addView(cancelButton);
            setContentView(linearLayout);
        }
    }

    @Override
    public void onDismiss(DialogInterface dialogInterface) {
        LinearLayout layout = ((Activity) context).findViewById(R.id.checkBoxLayout);
        layout.removeAllViews();
        CheckBox cbAll = ((Activity) context).findViewById(R.id.checkBox);
        cbAll.setChecked(checkAll);
        for (int i = 0; i < items.length; i++) {
            CheckBox cb = checkBoxList.get(i);
            checkedItems[i] = cb.isChecked();
            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            layoutParams.setMargins(5, 5, 5, 5);
            layout.addView(cb, layoutParams);
        }
        if (selectedList.isEmpty()) {
            ((Activity) context).findViewById(R.id.dropdown).setVisibility(View.VISIBLE);
            ((Activity) context).findViewById(R.id.parent_layout).invalidate();
        } else {
            TextView tv = new TextView(context);
            tv.setSingleLine(false);
            tv.setText(selectedList.toString());
            layout.addView(tv);
            ((Activity) context).findViewById(R.id.dropdown).setVisibility(View.GONE);
            ((Activity) context).findViewById(R.id.parent_layout).invalidate();
        }
    }

    public ArrayList<String> getSelectedList() {
        return selectedList;
    }

    public boolean[] getCheckedItems() {
        return checkedItems;
    }

    public void setCheckedItems(boolean[] checkedItems) {
        this.checkedItems = checkedItems;
    }

    public boolean isCheckAll() {
        return checkAll;
    }

    public void setCheckAll(boolean checkAll) {
        this.checkAll = checkAll;
    }

    public void checkAllFunc() {
        for (int i = 0; i < checkBoxList.size(); i++) {
            checkBoxList.get(i).setChecked(true);
            checkedItems[i] = true;
        }
        checkAll = true;
    }
}
4. 在 Activity 中使用 MultiSelectDropdown

在 Activity 中调用 MultiSelectDialog 来作为 Spinner 的下拉选项,并根据选项的选择情况更新 Spinner 上的数据。

public class MainActivity extends AppCompatActivity {

    private String[] items = {"Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6", "Item 7", "Item 8", "Item 9", "Item 10", "Item 11", "Item 12"};
    private ArrayList<String> itemList = new ArrayList<>(Arrays.asList(items));
    private MyAdapter adapter;
    private Spinner dropdown;
    private boolean[] checkedItems = new boolean[items.length];
    private ArrayList<String> selectedList = new ArrayList<>();
    private LinearLayout checkBoxLayout;
    private CheckBox cbAll;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        dropdown = findViewById(R.id.dropdown);
        checkBoxLayout = findViewById(R.id.checkBoxLayout);
        cbAll = findViewById(R.id.checkBox);
        cbAll.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                boolean isChecked = cbAll.isChecked();
                for (int i = 0; i < checkedItems.length; i++) {
                    checkedItems[i] = isChecked;
                }
                for (CheckBox checkBox : checkBoxList) {
                    checkBox.setChecked(isChecked);
                }
            }
        });

        adapter = new MyAdapter(itemList, this);
        dropdown.setAdapter(adapter);
        dropdown.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    openDialog();
                }
                return true;
            }
        });
    }

    private void openDialog() {
        MultiSelectDialog dialog = new MultiSelectDialog(MainActivity.this, items);
        dialog.setCheckedItems(checkedItems);
        dialog.setCheckAll(cbAll.isChecked());
        dialog.show();
        dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
            @Override
            public void onDismiss(DialogInterface dialogInterface) {
                selectedList = dialog.getSelectedList();
                for (int i = 0; i < checkedItems.length; i++) {
                    checkedItems[i] = dialog.getCheckedItems()[i];
                }
                if (selectedList.isEmpty()) {
                    cbAll.setChecked(false);
                    checkBoxLayout.removeAllViews();
                    dropdown.setVisibility(View.VISIBLE);
                    adapter.clear();
                    adapter.addAll(items);
                } else {
                    cbAll.setChecked(true);
                    String selected = selectedList.toString().replace("[", "").replace("]", "").trim();
                    checkBoxLayout.removeAllViews();
                    TextView tv = new TextView(MainActivity.this);
                    tv.setSingleLine(false);
                    tv.setText(selected);
                    checkBoxLayout.addView(tv);
                    dropdown.setVisibility(View.GONE);
                    adapter.clear();
                    adapter.add(selected);
                }
            }
        });
    }

}
结论

MultiSelectDropdown 在 Android 设备的应用程序中很普遍。

本篇文章演示了如何使用 Spinner 和 CheckBox 来创建一个 MultiSelect Dropdown。

完整的代码示例