@@ -76,6 +76,14 @@ static class MultiChoiceItem<E> {
7676 this .isSelected = false ;
7777 this .isDisabled = false ;
7878 }
79+
80+ MultiChoiceItem (@ NonNull MultiChoiceItem <E > other ) {
81+ this .id = other .id ;
82+ this .name = other .name ;
83+ this .rawItem = other .rawItem ;
84+ this .isSelected = other .isSelected ;
85+ this .isDisabled = other .isDisabled ;
86+ }
7987 }
8088
8189 public SearchableMultiChoiceDialogBuilder (@ NonNull Context context , @ NonNull List <T > items , @ ArrayRes int itemNames ) {
@@ -285,6 +293,8 @@ class SearchableRecyclerViewAdapter extends ListAdapter<MultiChoiceItem<T>, Sear
285293 final List <MultiChoiceItem <T >> mMasterList = new ArrayList <>();
286294 @ NonNull
287295 final List <T > mNotFoundItems = new ArrayList <>();
296+ @ NonNull
297+ List <MultiChoiceItem <T >> mCurrentVisibleList = new ArrayList <>();
288298 @ LayoutRes
289299 private final int mLayoutId ;
290300 @ Nullable
@@ -308,21 +318,20 @@ void setFilteredItems(CharSequence constraint) {
308318
309319 private void dispatchFilteredList () {
310320 if (mCurrentQuery == null || mCurrentQuery .length () == 0 ) {
311- submitList (new ArrayList <>(mMasterList ));
312- return ;
313- }
314-
315- Locale locale = Locale .getDefault ();
316- String query = mCurrentQuery .toString ().toLowerCase (locale );
317- List <MultiChoiceItem <T >> filteredList = new ArrayList <>();
318-
319- for (MultiChoiceItem <T > item : mMasterList ) {
320- if (item .name .toString ().toLowerCase (locale ).contains (query )
321- || item .rawItem .toString ().toLowerCase (Locale .ROOT ).contains (query )) {
322- filteredList .add (item );
321+ mCurrentVisibleList = new ArrayList <>(mMasterList );
322+ } else {
323+ Locale locale = Locale .getDefault ();
324+ String query = mCurrentQuery .toString ().toLowerCase (locale );
325+ List <MultiChoiceItem <T >> filteredList = new ArrayList <>();
326+ for (MultiChoiceItem <T > item : mMasterList ) {
327+ if (item .name .toString ().toLowerCase (locale ).contains (query )
328+ || item .rawItem .toString ().toLowerCase (Locale .ROOT ).contains (query )) {
329+ filteredList .add (item );
330+ }
323331 }
332+ mCurrentVisibleList = filteredList ;
324333 }
325- submitList (filteredList );
334+ submitList (mCurrentVisibleList );
326335 }
327336
328337 ArrayList <T > getSelectedItems () {
@@ -337,20 +346,29 @@ ArrayList<T> getSelectedItems() {
337346
338347 void addSelectedItems (@ Nullable List <T > selectedItems ) {
339348 if (selectedItems == null ) return ;
349+ boolean listUpdated = false ;
340350 for (T item : selectedItems ) {
341351 boolean found = false ;
342- for (MultiChoiceItem <T > wrapper : mMasterList ) {
352+ for (int i = 0 ; i < mMasterList .size (); i ++) {
353+ MultiChoiceItem <T > wrapper = mMasterList .get (i );
343354 if (Objects .equals (wrapper .rawItem , item )) {
344- wrapper .isSelected = true ;
355+ if (!wrapper .isSelected ) {
356+ MultiChoiceItem <T > newItem = new MultiChoiceItem <>(wrapper );
357+ newItem .isSelected = true ;
358+ mMasterList .set (i , newItem );
359+ listUpdated = true ;
360+ }
345361 found = true ;
346362 break ;
347363 }
348364 }
349- if (!found ) {
365+ if (!found && ! mNotFoundItems . contains ( item ) ) {
350366 mNotFoundItems .add (item );
351367 }
352368 }
353- dispatchFilteredList ();
369+ if (listUpdated ) {
370+ dispatchFilteredList ();
371+ }
354372 }
355373
356374 void addSelectedIndexes (@ Nullable int [] selectedIndexes ) {
@@ -393,35 +411,44 @@ void addDisabledItems(@Nullable List<T> disabledItems) {
393411 }
394412
395413 void selectAll () {
396- List < MultiChoiceItem < T >> visibleItems = getCurrentList () ;
397- for (MultiChoiceItem <T > item : visibleItems ) {
414+ boolean listUpdated = false ;
415+ for (MultiChoiceItem <T > item : mCurrentVisibleList ) {
398416 if (!item .isSelected ) {
399- item .isSelected = true ;
400- triggerMultiChoiceClickListener (item .id , true );
417+ MultiChoiceItem <T > newItem = new MultiChoiceItem <>(item );
418+ newItem .isSelected = true ;
419+ mMasterList .set (newItem .id , newItem );
420+ triggerMultiChoiceClickListener (newItem .id , true );
421+ listUpdated = true ;
401422 }
402423 }
403- checkSelections ();
404- dispatchFilteredList ();
424+ if (listUpdated ) {
425+ dispatchFilteredList ();
426+ checkSelections ();
427+ }
405428 }
406429
407430 void deselectAll () {
408- List < MultiChoiceItem < T >> visibleItems = getCurrentList () ;
409- for (MultiChoiceItem <T > item : visibleItems ) {
431+ boolean listUpdated = false ;
432+ for (MultiChoiceItem <T > item : mCurrentVisibleList ) {
410433 if (item .isSelected ) {
411- item .isSelected = false ;
412- triggerMultiChoiceClickListener (item .id , false );
434+ MultiChoiceItem <T > newItem = new MultiChoiceItem <>(item );
435+ newItem .isSelected = false ;
436+ mMasterList .set (newItem .id , newItem );
437+ triggerMultiChoiceClickListener (newItem .id , false );
438+ listUpdated = true ;
413439 }
414440 }
415- checkSelections ();
416- dispatchFilteredList ();
441+ if (listUpdated ) {
442+ dispatchFilteredList ();
443+ checkSelections ();
444+ }
417445 }
418446
419447 boolean areAllSelected () {
420- List <MultiChoiceItem <T >> visibleItems = getCurrentList ();
421- if (visibleItems .isEmpty ()) {
448+ if (mCurrentVisibleList .isEmpty ()) {
422449 return false ;
423450 }
424- for (MultiChoiceItem <T > item : visibleItems ) {
451+ for (MultiChoiceItem <T > item : mCurrentVisibleList ) {
425452 if (!item .isSelected ) {
426453 return false ;
427454 }
@@ -439,17 +466,17 @@ public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
439466 @ Override
440467 public void onBindViewHolder (@ NonNull SearchableRecyclerViewAdapter .ViewHolder holder , int position ) {
441468 MultiChoiceItem <T > item = getItem (position );
442-
443469 holder .item .setText (item .name );
444470 holder .item .setTextIsSelectable (mIsTextSelectable );
445471 holder .item .setEnabled (!item .isDisabled );
446472 holder .item .setChecked (item .isSelected );
447-
448473 holder .item .setOnClickListener (v -> {
449- item .isSelected = !item .isSelected ;
450- holder .item .setChecked (item .isSelected );
474+ MultiChoiceItem <T > newItem = new MultiChoiceItem <>(item );
475+ newItem .isSelected = !item .isSelected ;
476+ mMasterList .set (newItem .id , newItem );
477+ dispatchFilteredList ();
451478 checkSelections ();
452- triggerMultiChoiceClickListener (item .id , item .isSelected );
479+ triggerMultiChoiceClickListener (newItem .id , newItem .isSelected );
453480 });
454481 }
455482
0 commit comments