Evolver: Defer applying divider

Android 16 QPR1 + M3E changes the inflation and lifecycle timing of
PreferenceFragmentCompat layouts, resulting in internal RecyclerView
being created later than before.

As a result, PreferenceFragmentCompat.setDivider() can be invoked
before the internal RecyclerView exists thus causing below NPE:

https://paste.evolution-x.org/bESR1b

Test: Open System profiles settings, create a new profile and verify
      that the activity no longer crashes.
Change-Id: Ifb741011baaa6d721d0ca0db2d68d30037eb8930

https://paste.evolution-x.org/foaHLQ
This commit is contained in:
Bruno Martins
2025-11-26 20:21:00 +09:00
committed by Joey
parent 6f2903cf8b
commit ce896fdb79
5 changed files with 74 additions and 0 deletions

View File

@@ -17,6 +17,7 @@
package org.evolution.settings.fragments
import android.content.Context
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.os.Handler
import android.os.Looper
@@ -216,4 +217,20 @@ abstract class OptimizedSettingsFragment : SettingsPreferenceFragment() {
protected fun removeCallbacks() {
mHandler?.removeCallbacksAndMessages(null)
}
/**
* Fix crash: RecyclerView is sometimes null when setDivider() is called.
* We retry after view is attached instead of crashing.
*/
override fun setDivider(divider: Drawable?) {
val list = listView
if (list == null) {
view?.post {
if (isAdded) setDivider(divider)
}
return
}
super.setDivider(divider)
}
}

View File

@@ -22,6 +22,7 @@ import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
@@ -79,6 +80,20 @@ public class Fonts extends SettingsPreferenceFragment {
}
}
@Override
public void setDivider(@Nullable final Drawable divider) {
RecyclerView list = getListView();
if (list == null) {
View root = getView();
if (root != null) {
root.post(() -> setDivider(divider));
}
return;
}
super.setDivider(divider);
}
@Override
public int getMetricsCategory() {
return MetricsEvent.EVOLVER;

View File

@@ -105,6 +105,20 @@ public class NavigationBarIcons extends SettingsPreferenceFragment {
return view;
}
@Override
public void setDivider(@Nullable final Drawable divider) {
RecyclerView list = getListView();
if (list == null) {
View root = getView();
if (root != null) {
root.post(() -> setDivider(divider));
}
return;
}
super.setDivider(divider);
}
@Override
public int getMetricsCategory() {
return MetricsEvent.EVOLVER;

View File

@@ -103,6 +103,20 @@ public class UdfpsAnimations extends SettingsPreferenceFragment {
return view;
}
@Override
public void setDivider(@Nullable final Drawable divider) {
RecyclerView list = getListView();
if (list == null) {
View root = getView();
if (root != null) {
root.post(() -> setDivider(divider));
}
return;
}
super.setDivider(divider);
}
@Override
public int getMetricsCategory() {
return MetricsEvent.EVOLVER;

View File

@@ -110,6 +110,20 @@ public class UdfpsIcons extends SettingsPreferenceFragment {
return view;
}
@Override
public void setDivider(@Nullable final Drawable divider) {
RecyclerView list = getListView();
if (list == null) {
View root = getView();
if (root != null) {
root.post(() -> setDivider(divider));
}
return;
}
super.setDivider(divider);
}
@Override
public int getMetricsCategory() {
return MetricsEvent.EVOLVER;