2222import androidx .preference .Preference ;
2323import androidx .preference .PreferenceCategory ;
2424import androidx .preference .PreferenceFragmentCompat ;
25- import androidx .preference .PreferenceGroupAdapter ;
25+ import androidx .preference .PreferenceGroup ;
26+ import androidx .preference .PreferenceScreen ;
27+
28+ import java .util .ArrayList ;
29+ import java .util .List ;
2630import androidx .preference .SwitchPreferenceCompat ;
2731import androidx .recyclerview .widget .RecyclerView ;
2832
@@ -247,13 +251,17 @@ public void onChildViewDetachedFromWindow(@NonNull View view) {
247251
248252 private void updatePreferenceCardShapes (@ NonNull RecyclerView listView ) {
249253 RecyclerView .Adapter <?> adapter = listView .getAdapter ();
250- if (!(adapter instanceof PreferenceGroupAdapter )) {
254+ if (adapter == null ) {
255+ return ;
256+ }
257+ PreferenceScreen screen = getPreferenceScreen ();
258+ if (screen == null ) {
251259 return ;
252260 }
253- PreferenceGroupAdapter preferenceAdapter = ( PreferenceGroupAdapter ) adapter ;
254- int itemCount = preferenceAdapter . getItemCount ();
261+ List < Preference > visiblePreferences = getVisiblePreferences ( screen ) ;
262+ int itemCount = Math . min ( adapter . getItemCount (), visiblePreferences . size () );
255263 for (int position = 0 ; position < itemCount ; position ++) {
256- Preference preference = preferenceAdapter . getItem (position );
264+ Preference preference = visiblePreferences . get (position );
257265 if (preference instanceof PreferenceCategory ) {
258266 continue ;
259267 }
@@ -265,38 +273,32 @@ private void updatePreferenceCardShapes(@NonNull RecyclerView listView) {
265273 if (!(itemView instanceof MaterialCardView )) {
266274 continue ;
267275 }
268- boolean first = isFirstPreferenceInSection (preferenceAdapter , position );
269- boolean last = isLastPreferenceInSection (preferenceAdapter , position );
276+ boolean first = isFirstPreferenceInSection (visiblePreferences , position );
277+ boolean last = isLastPreferenceInSection (visiblePreferences , position );
270278 applyRoundedCorners ((MaterialCardView ) itemView , first , last );
271279 syncAccessoryVisibility (itemView );
272280 }
273281 }
274282
275- private boolean isFirstPreferenceInSection (@ NonNull PreferenceGroupAdapter adapter , int position ) {
283+ private boolean isFirstPreferenceInSection (@ NonNull List < Preference > preferences , int position ) {
276284 for (int index = position - 1 ; index >= 0 ; index --) {
277- Preference previous = adapter . getItem (index );
285+ Preference previous = preferences . get (index );
278286 if (!previous .isVisible ()) {
279287 continue ;
280288 }
281- if (previous instanceof PreferenceCategory ) {
282- return true ;
283- }
284- return false ;
289+ return previous instanceof PreferenceCategory ;
285290 }
286291 return true ;
287292 }
288293
289- private boolean isLastPreferenceInSection (@ NonNull PreferenceGroupAdapter adapter , int position ) {
290- int itemCount = adapter . getItemCount ();
294+ private boolean isLastPreferenceInSection (@ NonNull List < Preference > preferences , int position ) {
295+ int itemCount = preferences . size ();
291296 for (int index = position + 1 ; index < itemCount ; index ++) {
292- Preference next = adapter . getItem (index );
297+ Preference next = preferences . get (index );
293298 if (!next .isVisible ()) {
294299 continue ;
295300 }
296- if (next instanceof PreferenceCategory ) {
297- return true ;
298- }
299- return false ;
301+ return next instanceof PreferenceCategory ;
300302 }
301303 return true ;
302304 }
@@ -322,8 +324,7 @@ private void syncAccessoryVisibility(@NonNull View itemView) {
322324 icon .setVisibility (showIcon ? View .VISIBLE : View .GONE );
323325 }
324326 View widgetFrame = itemView .findViewById (android .R .id .widget_frame );
325- if (widgetFrame instanceof ViewGroup ) {
326- ViewGroup widgetGroup = (ViewGroup ) widgetFrame ;
327+ if (widgetFrame instanceof ViewGroup widgetGroup ) {
327328 boolean hasChild = widgetGroup .getChildCount () > 0 ;
328329 widgetFrame .setVisibility (hasChild ? View .VISIBLE : View .GONE );
329330 if (hasChild ) {
@@ -335,7 +336,28 @@ private void syncAccessoryVisibility(@NonNull View itemView) {
335336 }
336337 }
337338
338- private static class PreferenceSpacingDecoration extends RecyclerView .ItemDecoration {
339+ @ NonNull
340+ private List <Preference > getVisiblePreferences (@ NonNull PreferenceGroup group ) {
341+ List <Preference > preferences = new ArrayList <>();
342+ collectVisiblePreferences (group , preferences );
343+ return preferences ;
344+ }
345+
346+ private void collectVisiblePreferences (@ NonNull PreferenceGroup group ,
347+ @ NonNull List <Preference > out ) {
348+ for (int index = 0 ; index < group .getPreferenceCount (); index ++) {
349+ Preference preference = group .getPreference (index );
350+ if (!preference .isVisible ()) {
351+ continue ;
352+ }
353+ out .add (preference );
354+ if (preference instanceof PreferenceGroup && !(preference instanceof PreferenceScreen )) {
355+ collectVisiblePreferences ((PreferenceGroup ) preference , out );
356+ }
357+ }
358+ }
359+
360+ private class PreferenceSpacingDecoration extends RecyclerView .ItemDecoration {
339361 private final int spacing ;
340362
341363 PreferenceSpacingDecoration (@ NonNull Context context ) {
@@ -346,15 +368,19 @@ private static class PreferenceSpacingDecoration extends RecyclerView.ItemDecora
346368 @ Override
347369 public void getItemOffsets (@ NonNull Rect outRect , @ NonNull View view ,
348370 @ NonNull RecyclerView parent , @ NonNull RecyclerView .State state ) {
349- RecyclerView . Adapter <?> adapter = parent . getAdapter ();
350- if (!( adapter instanceof PreferenceGroupAdapter ) ) {
371+ PreferenceScreen screen = getPreferenceScreen ();
372+ if (screen == null ) {
351373 return ;
352374 }
353375 int position = parent .getChildAdapterPosition (view );
354376 if (position == RecyclerView .NO_POSITION ) {
355377 return ;
356378 }
357- Preference preference = ((PreferenceGroupAdapter ) adapter ).getItem (position );
379+ List <Preference > preferences = getVisiblePreferences (screen );
380+ if (position >= preferences .size ()) {
381+ return ;
382+ }
383+ Preference preference = preferences .get (position );
358384 if (!(preference instanceof PreferenceCategory )) {
359385 outRect .bottom = spacing ;
360386 }
0 commit comments