📅  最后修改于: 2023-12-03 15:24:06.570000             🧑  作者: Mango
实现 MultiSelect Dropdown 有多种方法,但最常用的方法是使用 Spinner 和 CheckBox 组合。此方法的好处是易于使用和理解,并且与 Android 设备的 UI 一致。
创建一个布局文件并添加 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>
创建一个 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;
}
}
创建一个 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;
}
}
在 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。