Almost finished clickable preference category paths.

TODO's if this is to be finished:
 - Hide search bar after clicking a preference category
 - Dismissing search bar needs to pop navigation back to root view
This commit is contained in:
LisoUseInAIKyrios 2025-05-10 02:32:15 +04:00
parent ec5ba866cc
commit ad5f23c86b
2 changed files with 67 additions and 4 deletions

View file

@ -192,7 +192,7 @@ public class SearchViewController {
if (isSearchActive) {
closeSearch();
} else {
activity.onBackPressed();
fragment.toolbarBackButtonPressed();
}
} catch (Exception ex) {
Logger.printException(() -> "navigation click failure", ex);

View file

@ -74,6 +74,11 @@ public class ReVancedPreferenceFragment extends AbstractPreferenceFragment {
*/
private final List<AbstractPreferenceSearchData<?>> allPreferences = new ArrayList<>();
/**
* Used to navigate to a PreferenceScreen when a search result category is clicked.
*/
private final Deque<PreferenceScreen> searchNavigationStack = new ArrayDeque<>();
@SuppressLint("UseCompatLoadingForDrawables")
public static Drawable getBackButtonDrawable() {
final int backButtonResource = getResourceIdentifier(ThemeHelper.isDarkTheme()
@ -187,6 +192,21 @@ public class ReVancedPreferenceFragment extends AbstractPreferenceFragment {
}
}
public void navigateToScreen(PreferenceScreen subScreen) {
searchNavigationStack.push(preferenceScreen);
setPreferenceScreen(subScreen);
}
public void toolbarBackButtonPressed() {
if (searchNavigationStack.isEmpty()) {
getActivity().onBackPressed();
return;
}
setPreferenceScreen(searchNavigationStack.pop());
}
/**
* Recursively collects all preferences from the screen or group.
* @param includeDepth Menu depth to start including preferences.
@ -236,7 +256,7 @@ public class ReVancedPreferenceFragment extends AbstractPreferenceFragment {
}
// Navigation path -> Category
Map<String, PreferenceCategory> categoryMap = new HashMap<>();
Map<String, ClickablePreferenceCategory> categoryMap = new HashMap<>();
String queryLower = Utils.removePunctuationToLowercase(query);
Pattern queryPattern = Pattern.compile(Pattern.quote(Utils.removePunctuationToLowercase(query)),
@ -247,8 +267,8 @@ public class ReVancedPreferenceFragment extends AbstractPreferenceFragment {
data.applyHighlighting(queryLower, queryPattern);
String navigationPath = data.navigationPath;
PreferenceCategory group = categoryMap.computeIfAbsent(navigationPath, key -> {
PreferenceCategory newGroup = new PreferenceCategory(preferenceScreen.getContext());
ClickablePreferenceCategory group = categoryMap.computeIfAbsent(navigationPath, key -> {
ClickablePreferenceCategory newGroup = new ClickablePreferenceCategory(this, data.parentScreen);
newGroup.setTitle(navigationPath);
preferenceScreen.addPreference(newGroup);
return newGroup;
@ -401,6 +421,21 @@ class AbstractPreferenceSearchData<T extends Preference> {
return spannable;
}
private static PreferenceScreen getParentScreen(Preference preference) {
while (true) {
preference = preference.getParent();
if (preference instanceof PreferenceScreen screen) {
return screen;
}
if (preference == null) {
return null;
}
}
}
final PreferenceScreen parentScreen;
final T preference;
final String key;
final String navigationPath;
@ -412,6 +447,7 @@ class AbstractPreferenceSearchData<T extends Preference> {
String searchTitle;
AbstractPreferenceSearchData(T pref) {
parentScreen = getParentScreen(pref);
preference = pref;
key = Utils.removePunctuationToLowercase(pref.getKey());
navigationPath = getPreferenceNavigationString(pref);
@ -602,3 +638,30 @@ class ListPreferenceSearchData extends AbstractPreferenceSearchData<ListPreferen
preference.setEntries(originalEntries);
}
}
@SuppressWarnings("deprecation")
class ClickablePreferenceCategory extends PreferenceCategory {
public ClickablePreferenceCategory(ReVancedPreferenceFragment fragment,
@Nullable PreferenceScreen subScreen) {
super(fragment.getContext());
if (subScreen != null) {
setOnPreferenceClickListener(preference -> {
fragment.navigateToScreen(subScreen);
return true;
});
}
}
@Override
public boolean isEnabled() {
return true;
}
@Override
public boolean isSelectable() {
return true;
}
}