Create checkboxes dropdown component

This commit is contained in:
elena 2022-12-13 15:20:00 +00:00
parent 780a215a6b
commit 51698947aa
4 changed files with 196 additions and 0 deletions

View File

@ -0,0 +1,175 @@
package com.beemdevelopment.aegis.ui.components;
import android.content.Context;
import android.content.res.TypedArray;
import android.text.InputType;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.Filter;
import android.widget.Filterable;
import androidx.annotation.PluralsRes;
import androidx.appcompat.widget.AppCompatAutoCompleteTextView;
import com.beemdevelopment.aegis.R;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;
public class DropdownCheckBoxes extends AppCompatAutoCompleteTextView {
private @PluralsRes int _selectedCountPlural = R.plurals.dropdown_checkboxes_default_count;
private boolean _allowFiltering = false;
private final List<String> _items = new ArrayList<>();
private List<String> _visibleItems = new ArrayList<>();
private final Set<String> _checkedItems = new TreeSet<>();
private CheckboxAdapter _adapter;
public DropdownCheckBoxes(Context context) {
super(context);
initialise(context, null);
}
public DropdownCheckBoxes(Context context, AttributeSet attrs) {
super(context, attrs);
initialise(context, attrs);
}
public DropdownCheckBoxes(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initialise(context, attrs);
}
private void initialise(Context context, AttributeSet attrs) {
_adapter = new CheckboxAdapter();
setAdapter(_adapter);
if (attrs != null) {
TypedArray a = context.obtainStyledAttributes(
attrs,
R.styleable.DropdownCheckBoxes,
0, 0);
_allowFiltering = a.getBoolean(R.styleable.DropdownCheckBoxes_allow_filtering, false);
a.recycle();
}
if (!_allowFiltering) {
setInputType(0);
} else {
setInputType(InputType.TYPE_CLASS_TEXT);
}
}
public void addItems(List<String> items, boolean startChecked) {
_items.addAll(items);
_visibleItems.addAll(items);
if (startChecked) {
_checkedItems.addAll(items);
}
updateCheckedItemsCountText();
_adapter.notifyDataSetChanged();
}
private void updateCheckedItemsCountText() {
if (_allowFiltering) {
return;
}
int count = _checkedItems.size();
String countString = getResources().getQuantityString(_selectedCountPlural, count, count);
setText(countString, false);
}
public void setCheckedItemsCountTextRes(@PluralsRes int resId) {
_selectedCountPlural = resId;
}
public Set<String> getCheckedItems() {
return _checkedItems;
}
private class CheckboxAdapter extends BaseAdapter implements Filterable {
@Override
public int getCount() {
return _visibleItems.size();
}
@Override
public String getItem(int i) {
return _visibleItems.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View convertView, ViewGroup viewGroup) {
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.dropdown_checkbox, viewGroup, false);
}
String item = _visibleItems.get(i);
CheckBox checkBox = convertView.findViewById(R.id.checkbox_in_dropdown);
checkBox.setText(item);
checkBox.setChecked(_checkedItems.contains(item));
checkBox.setOnCheckedChangeListener((buttonView, isChecked) -> {
String label = buttonView.getText().toString();
if (isChecked) {
_checkedItems.add(label);
} else {
_checkedItems.remove(label);
}
updateCheckedItemsCountText();
});
return convertView;
}
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence query) {
FilterResults results = new FilterResults();
results.values = (query == null || query.toString().isEmpty())
? _items
: _items.stream().filter(str -> {
String q = query.toString().toLowerCase();
String strLower = str.toLowerCase();
return strLower.contains(q);
})
.collect(Collectors.toList());
return results;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
_visibleItems = (List<String>) filterResults.values;
notifyDataSetChanged();
}
};
}
}
}

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<CheckBox
android:id="@+id/checkbox_in_dropdown"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:buttonTint="@color/colorSecondary"/>
</androidx.appcompat.widget.LinearLayoutCompat>

View File

@ -19,4 +19,8 @@
<attr name="dot_color" format="color" />
<attr name="dot_color_selected" format="color" />
</declare-styleable>
<declare-styleable name="DropdownCheckBoxes">
<attr name="allow_filtering" format="boolean" />
</declare-styleable>
</resources>

View File

@ -500,4 +500,9 @@
<item quantity="one">%d year ago</item>
<item quantity="other">%d years ago</item>
</plurals>
<plurals name="dropdown_checkboxes_default_count">
<item quantity="one">%d item selected</item>
<item quantity="other">%d items selected</item>
</plurals>
</resources>