Skip to content

CustomListDialog

Eltos edited this page Oct 29, 2021 · 10 revisions

Dialogs with custom lists

extends CustomViewDialog

API reference

This class provides the basic functionality to work with list based dialogs. Extend this class to create a dialog with a custom list. The most simple implementation is the SimpleListDialog. All elements in the list are referred to either by their original position or and ID (if provided). The list can also be filtered.

Usage

For general usage see SimpleDialog.

Additional methods are provided for customization:

  • Choice mode (choiceMode)
    • NO_CHOICE - items can not be selected
    • SINGLE_CHOICE - only one item can be selected at a time
    • SINGLE_CHOICE_DIRECT - selecting an item closes the dialog as if the positive button was pressed
    • MULTI_CHOICE - multiple items can be (un-)selected
  • Choice preset(s) (choicePreset or choiceIdPreset)
  • Required choice count (choiceMin and choiceMax)
  • Filter (filterable)
    When enabled, a search box appears at the top, so the user can filter the list by searching for a keyword.
  • Layout (grid, gridNumColumn, gridColumnWidth)
    Allows to enable a grid layout instead of the default vertical list layout
  • Divider (divider)

Please refer to the API reference for a comprehensive documentation of these methods.

Receiving results

For general usage see SimpleDialog.

The extras Bundle returned will contain the following additional keys indicating the selected IDs and positions:

// Only for `SINGLE_CHOICE`- and `SINGLE_CHOICE_DIRECT`-modes:
long id = extras.getLong(CustomListDialog.SELECTED_SINGLE_ID);
int pos = extras.getInt(CustomListDialog.SELECTED_SINGLE_POSITION);

// For all modes except `NO_CHOICE`:
long[] ids = extras.getLongArray(CustomListDialog.SELECTED_IDS);
ArrayList<Integer> positions = extras.getIntegerArrayList(CustomListDialog.SELECTED_POSITIONS);

Custom implementation

In addition to the guide below, you can have a look at the implementation of SimpleListDialog.

Extend the class like this:

public class MyListDialog extends CustomListDialog<MyListDialog> {

    public static final String TAG = "MyListDialog.";
    
    public static MyListDialog build(){
        return new MyListDialog()
                    .pos(R.string.customDefaultText); // can be useful to provide presets here
    }
    
    
    protected static final String
            DATA_SET = TAG + "data";

    /**
     * Some method which will allow us to set data later in a persistent manner...
     */
    public MyListDialog items(ArrayList<SimpleListItem> items){
        getArgs().putParcelableArrayList(DATA_SET, items);
        return this;
    }
    
    // ...
}

For details on the TAG, build method and getArgs in the above example please refer to CustomViewDialog.

Adapter

Create a custom adapter class which must extend AdvancedAdapter).

Implement onCreateAdapter to instantiate and return your adapter.

In this example the SimpleListItem is used for convenience, but you can use any data structure as long as you set the data to your adapter by calling setDataAndIds

    @Override
    protected MyListDialog onCreateAdapter() {

        // retrieve the data set with the items method when using our custom dialog
        mData = getArgs().getParcelableArrayList(DATA_SET);
        if (mData == null) mData = new ArrayList<>(0);

        return new MyListAdapter(R.layout.myListDialogItemLayout, mData);

    }
    
    
    class MyListAdapter extends AdvancedAdapter<String> {
        private int mLayout;

        // We set data in constructor

        MyListAdapter(@LayoutRes int layout, ArrayList<SimpleListItem> data){
            mLayout = layout;
            ArrayList<Pair<String, Long>> dataAndIds = new ArrayList<>(data.size());
            for (SimpleListItem simpleListItem : data) {
                dataAndIds.add(new Pair<>(simpleListItem.getString(), simpleListItem.getId()));
            }
            // set the data (String in this case) and IDs to the adapter
            setDataAndIds(dataAndIds);
        }

        
        // Provide an optional implementation to filter the dataset
        
        AdvancedFilter mFilter = new AdvancedFilter(true, true){
            @Override
            protected boolean matches(String object, @NonNull CharSequence constraint) {
                return matches(object);
            }
        };

        @Override
        public AdvancedFilter getFilter() {
            return mFilter;
        }

        
        // Inflate or update item view
        
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            TextView textView;

            if (convertView == null){
                convertView = inflate(mLayout, parent, false);
                textView = (TextView) convertView.findViewById(android.R.id.text1);
                convertView.setTag(textView);
            } else {
                textView = (TextView) convertView.getTag();
            }

            textView.setText(getItem(position));

            return super.getView(position, convertView, parent);
        }

    }
    

Handling clicks

Overwrite these methods to perform additional actions for clicks and long clicks on list items. You do not have to take care of selecting items here, as this is done automatically.