126 lines
4.9 KiB
Java
126 lines
4.9 KiB
Java
package org.schabi.newpipe.settings.preferencesearch;
|
|
|
|
import android.content.res.Resources;
|
|
import android.content.res.TypedArray;
|
|
import android.graphics.PorterDuff;
|
|
import android.graphics.PorterDuffColorFilter;
|
|
import android.graphics.drawable.Drawable;
|
|
import android.graphics.drawable.RippleDrawable;
|
|
import android.os.Handler;
|
|
import android.os.Looper;
|
|
import android.util.Log;
|
|
import android.util.TypedValue;
|
|
|
|
import androidx.appcompat.content.res.AppCompatResources;
|
|
import androidx.preference.Preference;
|
|
import androidx.preference.PreferenceFragmentCompat;
|
|
import androidx.preference.PreferenceGroup;
|
|
import androidx.recyclerview.widget.RecyclerView;
|
|
|
|
import org.schabi.newpipe.R;
|
|
|
|
|
|
public final class PreferenceSearchResultHighlighter {
|
|
private static final String TAG = "PrefSearchResHighlter";
|
|
|
|
private PreferenceSearchResultHighlighter() {
|
|
}
|
|
|
|
/**
|
|
* Highlight the specified preference.
|
|
* <br/>
|
|
* Note: This function is Thread independent (can be called from outside of the main thread).
|
|
*
|
|
* @param item The item to highlight
|
|
* @param prefsFragment The fragment where the items is located on
|
|
*/
|
|
public static void highlight(
|
|
final PreferenceSearchItem item,
|
|
final PreferenceFragmentCompat prefsFragment
|
|
) {
|
|
new Handler(Looper.getMainLooper()).post(() -> doHighlight(item, prefsFragment));
|
|
}
|
|
|
|
private static void doHighlight(
|
|
final PreferenceSearchItem item,
|
|
final PreferenceFragmentCompat prefsFragment
|
|
) {
|
|
final Preference prefResult = prefsFragment.findPreference(item.getKey());
|
|
|
|
if (prefResult == null) {
|
|
Log.w(TAG, "Preference '" + item.getKey() + "' not found on '" + prefsFragment + "'");
|
|
return;
|
|
}
|
|
|
|
final RecyclerView recyclerView = prefsFragment.getListView();
|
|
final RecyclerView.Adapter<?> adapter = recyclerView.getAdapter();
|
|
if (adapter instanceof PreferenceGroup.PreferencePositionCallback) {
|
|
final int position = ((PreferenceGroup.PreferencePositionCallback) adapter)
|
|
.getPreferenceAdapterPosition(prefResult);
|
|
if (position != RecyclerView.NO_POSITION) {
|
|
recyclerView.scrollToPosition(position);
|
|
recyclerView.postDelayed(() -> {
|
|
final RecyclerView.ViewHolder holder =
|
|
recyclerView.findViewHolderForAdapterPosition(position);
|
|
if (holder != null) {
|
|
final Drawable background = holder.itemView.getBackground();
|
|
if (background instanceof RippleDrawable) {
|
|
showRippleAnimation((RippleDrawable) background);
|
|
return;
|
|
}
|
|
}
|
|
highlightFallback(prefsFragment, prefResult);
|
|
}, 200);
|
|
return;
|
|
}
|
|
}
|
|
highlightFallback(prefsFragment, prefResult);
|
|
}
|
|
|
|
/**
|
|
* Alternative highlighting (shows an → arrow in front of the setting)if ripple does not work.
|
|
*
|
|
* @param prefsFragment
|
|
* @param prefResult
|
|
*/
|
|
private static void highlightFallback(
|
|
final PreferenceFragmentCompat prefsFragment,
|
|
final Preference prefResult
|
|
) {
|
|
// Get primary color from text for highlight icon
|
|
final TypedValue typedValue = new TypedValue();
|
|
final Resources.Theme theme = prefsFragment.getActivity().getTheme();
|
|
theme.resolveAttribute(android.R.attr.textColorPrimary, typedValue, true);
|
|
final TypedArray arr = prefsFragment.getActivity()
|
|
.obtainStyledAttributes(
|
|
typedValue.data,
|
|
new int[]{android.R.attr.textColorPrimary});
|
|
final int color = arr.getColor(0, 0xffE53935);
|
|
arr.recycle();
|
|
|
|
// Show highlight icon
|
|
final Drawable oldIcon = prefResult.getIcon();
|
|
final boolean oldSpaceReserved = prefResult.isIconSpaceReserved();
|
|
final Drawable highlightIcon =
|
|
AppCompatResources.getDrawable(
|
|
prefsFragment.requireContext(),
|
|
R.drawable.ic_play_arrow);
|
|
highlightIcon.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
|
|
prefResult.setIcon(highlightIcon);
|
|
|
|
prefsFragment.scrollToPreference(prefResult);
|
|
|
|
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
|
prefResult.setIcon(oldIcon);
|
|
prefResult.setIconSpaceReserved(oldSpaceReserved);
|
|
}, 1000);
|
|
}
|
|
|
|
private static void showRippleAnimation(final RippleDrawable rippleDrawable) {
|
|
rippleDrawable.setState(
|
|
new int[]{android.R.attr.state_pressed, android.R.attr.state_enabled});
|
|
new Handler(Looper.getMainLooper())
|
|
.postDelayed(() -> rippleDrawable.setState(new int[]{}), 1000);
|
|
}
|
|
}
|