20
20
import android .widget .Checkable ;
21
21
import android .widget .FrameLayout ;
22
22
23
- import java .util .HashSet ;
24
- import java .util .Set ;
25
-
26
23
import androidx .annotation .NonNull ;
27
24
import androidx .annotation .Nullable ;
28
25
import androidx .recyclerview .widget .RecyclerView ;
29
26
27
+ import java .util .HashSet ;
28
+ import java .util .Set ;
29
+
30
30
import de .mrapp .android .dialog .R ;
31
+ import de .mrapp .android .dialog .model .ListDialog .OnItemEnabledListener ;
31
32
import de .mrapp .android .dialog .model .ListDialog .OnItemSelectedListener ;
32
33
import de .mrapp .android .util .ThemeUtil ;
33
34
import de .mrapp .util .Condition ;
@@ -238,16 +239,26 @@ public T getWrappedViewHolder() {
238
239
*/
239
240
private final Handler handler ;
240
241
242
+ /**
243
+ * A set, which contains the positions of all disabled items.
244
+ */
245
+ private Set <Integer > disabledItems ;
246
+
241
247
/**
242
248
* The listener, which is notified, when a list item has been clicked.
243
249
*/
244
250
private OnItemClickListener itemClickListener ;
245
251
246
252
/**
247
- * The listener, which is notified, when a list item has been selected.
253
+ * The listener, which is notified, when a list item has been selected or unselected .
248
254
*/
249
255
private OnItemSelectedListener itemSelectedListener ;
250
256
257
+ /**
258
+ * The listener, which is notified, when a list item has been enabled or disabled.
259
+ */
260
+ private OnItemEnabledListener itemEnabledListener ;
261
+
251
262
/**
252
263
* Creates a listener, which allows to select a list item when it has been clicked.
253
264
*
@@ -294,6 +305,56 @@ public void run() {
294
305
};
295
306
}
296
307
308
+ /**
309
+ * Sets, whether the list item at a specific position should be enabled, or not.
310
+ *
311
+ * @param position The position of the list item, whose enable state should be changed, as an {@link
312
+ * Integer} value
313
+ * @param enabled True, if the list item should be enabled, false otherwise
314
+ * @return True, if the enable state of the item at the given position has changed, false
315
+ * otherwise
316
+ */
317
+ public final boolean setItemEnabledInternally (final int position , final boolean enabled ) {
318
+ boolean result = false ;
319
+
320
+ if (enabled ) {
321
+ if (disabledItems != null ) {
322
+ result = disabledItems .remove (position );
323
+
324
+ if (disabledItems .isEmpty ()) {
325
+ disabledItems = null ;
326
+ }
327
+ }
328
+ } else {
329
+ if (disabledItems == null ) {
330
+ disabledItems = new HashSet <>();
331
+ }
332
+
333
+ result = disabledItems .add (position );
334
+ }
335
+
336
+ return result ;
337
+ }
338
+
339
+ /**
340
+ * Sets the enable state of a specific view and all of its children.
341
+ *
342
+ * @param view The view, whose enable state should be set, as an instance of the class
343
+ * {@link View}. The view may not be null
344
+ * @param enabled True, if the view should be enabled, false otherwise
345
+ */
346
+ private void setViewEnabled (@ NonNull final View view , final boolean enabled ) {
347
+ view .setEnabled (enabled );
348
+
349
+ if (view instanceof ViewGroup ) {
350
+ ViewGroup viewGroup = (ViewGroup ) view ;
351
+
352
+ for (int i = 0 ; i < viewGroup .getChildCount (); i ++) {
353
+ setViewEnabled (viewGroup .getChildAt (i ), enabled );
354
+ }
355
+ }
356
+ }
357
+
297
358
/**
298
359
* Creates a new wrapper that encapsulates a recycler view adapter in order to manage the
299
360
* selection states of the adapter's list items.
@@ -314,6 +375,7 @@ public RecyclerViewAdapterWrapper(@NonNull final Context context,
314
375
this .wrappedAdapter = wrappedAdapter ;
315
376
this .choiceMode = choiceMode ;
316
377
this .handler = new Handler (context .getMainLooper ());
378
+ this .disabledItems = null ;
317
379
}
318
380
319
381
/**
@@ -327,7 +389,8 @@ public final void setOnItemClickListener(@Nullable final OnItemClickListener lis
327
389
}
328
390
329
391
/**
330
- * Sets the listener, which should be notified, when a list item has been selected.
392
+ * Sets the listener, which should be notified, when a list item has been selected or
393
+ * unselected.
331
394
*
332
395
* @param listener The listener, which should be set, as an instance of the type {@link
333
396
* OnItemSelectedListener} or null, if no listener should be notified
@@ -336,6 +399,16 @@ public final void setOnItemSelectedListener(@Nullable final OnItemSelectedListen
336
399
this .itemSelectedListener = listener ;
337
400
}
338
401
402
+ /**
403
+ * Sets the listener, which should be notified, when a list item has been enabled or disabled.
404
+ *
405
+ * @param listener The listener, which should be set, as an instance of the type
406
+ * {@link OnItemEnabledListener} or null, if no listener should be notified
407
+ */
408
+ public final void setOnItemEnabledListener (@ Nullable final OnItemEnabledListener listener ) {
409
+ this .itemEnabledListener = listener ;
410
+ }
411
+
339
412
/**
340
413
* Returns the choice mode, which is used by the adapter.
341
414
*
@@ -380,12 +453,55 @@ public final void setItemChecked(final int position, final boolean checked) {
380
453
if (choiceMode .setItemChecked (position , checked )) {
381
454
notifyDataSetChanged ();
382
455
383
- if (checked && itemSelectedListener != null ) {
384
- itemSelectedListener .onItemSelected (position );
456
+ if (itemSelectedListener != null ) {
457
+ itemSelectedListener .onItemSelectionStateChanged (position , checked );
458
+ }
459
+ }
460
+ }
461
+
462
+ /**
463
+ * Returns, whether the list item at a specific position is currently enabled, or not.
464
+ *
465
+ * @param position The position of the list item, whose enable state should be returned, as an {@link
466
+ * Integer} value
467
+ * @return True, if the list item is enabled, false otherwise
468
+ */
469
+ public final boolean isItemEnabled (final int position ) {
470
+ return disabledItems == null || !disabledItems .contains (position );
471
+ }
472
+
473
+ /**
474
+ * Sets, whether the list item at a specific position should be enabled, or not.
475
+ *
476
+ * @param position The position of the list item, whose enable state should be changed, as an {@link
477
+ * Integer} value
478
+ * @param enabled True, if the list item should be enabled, false otherwise
479
+ */
480
+ public final void setItemEnabled (final int position , final boolean enabled ) {
481
+ if (setItemEnabledInternally (position , enabled )) {
482
+ notifyDataSetChanged ();
483
+
484
+ if (itemEnabledListener != null ) {
485
+ itemEnabledListener .onItemEnableStateChanged (position , enabled );
385
486
}
386
487
}
387
488
}
388
489
490
+ @ Override
491
+ public final int getItemCount () {
492
+ return wrappedAdapter .getItemCount ();
493
+ }
494
+
495
+ @ Override
496
+ public final long getItemId (final int position ) {
497
+ return wrappedAdapter .getItemId (position );
498
+ }
499
+
500
+ @ Override
501
+ public final int getItemViewType (final int position ) {
502
+ return wrappedAdapter .getItemViewType (position );
503
+ }
504
+
389
505
@ NonNull
390
506
@ Override
391
507
public final ViewHolderWrapper <VH > onCreateViewHolder (@ NonNull final ViewGroup parent ,
@@ -408,26 +524,12 @@ public final void onBindViewHolder(@NonNull final ViewHolderWrapper<VH> holder,
408
524
wrappedAdapter .onBindViewHolder (wrappedViewHolder , position );
409
525
View view = holder .itemView ;
410
526
view .setOnClickListener (createItemClickListener (position ));
527
+ setViewEnabled (view , isItemEnabled (position ));
411
528
View wrappedView = wrappedViewHolder .itemView ;
412
529
413
530
if (wrappedView instanceof Checkable ) {
414
531
handler .post (createCheckableRunnable ((Checkable ) wrappedView , isItemChecked (position )));
415
532
}
416
533
}
417
534
418
- @ Override
419
- public final int getItemCount () {
420
- return wrappedAdapter .getItemCount ();
421
- }
422
-
423
- @ Override
424
- public final long getItemId (final int position ) {
425
- return wrappedAdapter .getItemId (position );
426
- }
427
-
428
- @ Override
429
- public final int getItemViewType (final int position ) {
430
- return wrappedAdapter .getItemViewType (position );
431
- }
432
-
433
535
}
0 commit comments