Revise homepage highlight mechanism
- Create TopLevelHighlightMixin to handle highlight actions and simplify TopLevelSettings - Fix the error highlight and the flicker after screen rotation - Postpone creating the fragment until it's needed to accelerate the initialization and to fix the search highlight function breakage after toggling light/dark mode - Register activity embedding rules only once for injection and wallpaper - Do not highlight Tips & support since it's full screen - Refactor ActivityEmbeddingRulesController Bug: 207316936 Test: manual, robotest build pass Change-Id: If322ec180b03ee123987c70779a25c6a570d9faf
This commit is contained in:
@@ -23,7 +23,6 @@ import android.content.Intent;
|
|||||||
import android.util.LayoutDirection;
|
import android.util.LayoutDirection;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.window.embedding.ActivityFilter;
|
import androidx.window.embedding.ActivityFilter;
|
||||||
import androidx.window.embedding.ActivityRule;
|
import androidx.window.embedding.ActivityRule;
|
||||||
import androidx.window.embedding.SplitController;
|
import androidx.window.embedding.SplitController;
|
||||||
@@ -114,7 +113,7 @@ public class ActivityEmbeddingRulesController {
|
|||||||
|
|
||||||
registerTwoPanePairRule(
|
registerTwoPanePairRule(
|
||||||
context,
|
context,
|
||||||
getComponentName(context, Settings.class),
|
new ComponentName(context, Settings.class),
|
||||||
secondaryComponent,
|
secondaryComponent,
|
||||||
secondaryIntentAction,
|
secondaryIntentAction,
|
||||||
finishPrimaryWithSecondary ? SplitRule.FINISH_ADJACENT : SplitRule.FINISH_NEVER,
|
finishPrimaryWithSecondary ? SplitRule.FINISH_ADJACENT : SplitRule.FINISH_NEVER,
|
||||||
@@ -123,7 +122,7 @@ public class ActivityEmbeddingRulesController {
|
|||||||
|
|
||||||
registerTwoPanePairRule(
|
registerTwoPanePairRule(
|
||||||
context,
|
context,
|
||||||
getComponentName(context, SettingsHomepageActivity.class),
|
new ComponentName(context, SettingsHomepageActivity.class),
|
||||||
secondaryComponent,
|
secondaryComponent,
|
||||||
secondaryIntentAction,
|
secondaryIntentAction,
|
||||||
finishPrimaryWithSecondary ? SplitRule.FINISH_ADJACENT : SplitRule.FINISH_NEVER,
|
finishPrimaryWithSecondary ? SplitRule.FINISH_ADJACENT : SplitRule.FINISH_NEVER,
|
||||||
@@ -143,7 +142,7 @@ public class ActivityEmbeddingRulesController {
|
|||||||
|
|
||||||
registerTwoPanePairRule(
|
registerTwoPanePairRule(
|
||||||
context,
|
context,
|
||||||
getComponentName(context, SliceDeepLinkHomepageActivity.class),
|
new ComponentName(context, SliceDeepLinkHomepageActivity.class),
|
||||||
secondaryComponent,
|
secondaryComponent,
|
||||||
secondaryIntentAction,
|
secondaryIntentAction,
|
||||||
finishPrimaryWithSecondary ? SplitRule.FINISH_ALWAYS : SplitRule.FINISH_NEVER,
|
finishPrimaryWithSecondary ? SplitRule.FINISH_ALWAYS : SplitRule.FINISH_NEVER,
|
||||||
@@ -179,7 +178,7 @@ public class ActivityEmbeddingRulesController {
|
|||||||
|
|
||||||
registerTwoPanePairRuleForSettingsHome(
|
registerTwoPanePairRuleForSettingsHome(
|
||||||
context,
|
context,
|
||||||
getComponentName(context, SubSettings.class),
|
new ComponentName(context, SubSettings.class),
|
||||||
null /* secondaryIntentAction */,
|
null /* secondaryIntentAction */,
|
||||||
clearTop);
|
clearTop);
|
||||||
}
|
}
|
||||||
@@ -191,8 +190,7 @@ public class ActivityEmbeddingRulesController {
|
|||||||
addActivityFilter(activityFilters, SliceDeepLinkHomepageActivity.class);
|
addActivityFilter(activityFilters, SliceDeepLinkHomepageActivity.class);
|
||||||
addActivityFilter(activityFilters, Settings.class);
|
addActivityFilter(activityFilters, Settings.class);
|
||||||
|
|
||||||
final Intent intent = new Intent();
|
final Intent intent = new Intent(mContext, Settings.NetworkDashboardActivity.class);
|
||||||
intent.setComponent(getComponentName(Settings.NetworkDashboardActivity.class));
|
|
||||||
final SplitPlaceholderRule placeholderRule = new SplitPlaceholderRule(
|
final SplitPlaceholderRule placeholderRule = new SplitPlaceholderRule(
|
||||||
activityFilters,
|
activityFilters,
|
||||||
intent,
|
intent,
|
||||||
@@ -215,23 +213,7 @@ public class ActivityEmbeddingRulesController {
|
|||||||
|
|
||||||
private void addActivityFilter(Set<ActivityFilter> activityFilters,
|
private void addActivityFilter(Set<ActivityFilter> activityFilters,
|
||||||
Class<? extends Activity> activityClass) {
|
Class<? extends Activity> activityClass) {
|
||||||
activityFilters.add(new ActivityFilter(getComponentName(activityClass),
|
activityFilters.add(new ActivityFilter(new ComponentName(mContext, activityClass),
|
||||||
null /* intentAction */));
|
null /* intentAction */));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addActivityFilter(Set<ActivityFilter> activityFilters,
|
|
||||||
ComponentName componentName) {
|
|
||||||
activityFilters.add(new ActivityFilter(componentName, null /* intentAction */));
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
private ComponentName getComponentName(Class<? extends Activity> activityClass) {
|
|
||||||
return getComponentName(mContext, activityClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
private static ComponentName getComponentName(Context context,
|
|
||||||
Class<? extends Activity> activityClass) {
|
|
||||||
return new ComponentName(context.getPackageName(), activityClass.getName());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -36,7 +36,6 @@ import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_TITL
|
|||||||
import android.app.settings.SettingsEnums;
|
import android.app.settings.SettingsEnums;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface.OnCancelListener;
|
|
||||||
import android.content.IContentProvider;
|
import android.content.IContentProvider;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
@@ -63,6 +62,7 @@ import com.android.settings.Utils;
|
|||||||
import com.android.settings.activityembedding.ActivityEmbeddingRulesController;
|
import com.android.settings.activityembedding.ActivityEmbeddingRulesController;
|
||||||
import com.android.settings.activityembedding.ActivityEmbeddingUtils;
|
import com.android.settings.activityembedding.ActivityEmbeddingUtils;
|
||||||
import com.android.settings.dashboard.profileselector.ProfileSelectDialog;
|
import com.android.settings.dashboard.profileselector.ProfileSelectDialog;
|
||||||
|
import com.android.settings.homepage.TopLevelHighlightMixin;
|
||||||
import com.android.settings.homepage.TopLevelSettings;
|
import com.android.settings.homepage.TopLevelSettings;
|
||||||
import com.android.settings.overlay.FeatureFactory;
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
import com.android.settings.widget.PrimarySwitchPreference;
|
import com.android.settings.widget.PrimarySwitchPreference;
|
||||||
@@ -170,27 +170,23 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider {
|
|||||||
if (action != null) {
|
if (action != null) {
|
||||||
intent.setAction(action);
|
intent.setAction(action);
|
||||||
}
|
}
|
||||||
|
// Register the rule for injected apps.
|
||||||
|
ActivityEmbeddingRulesController.registerTwoPanePairRuleForSettingsHome(
|
||||||
|
mContext,
|
||||||
|
new ComponentName(tile.getPackageName(), tile.getComponentName()),
|
||||||
|
action,
|
||||||
|
true /* clearTop */);
|
||||||
pref.setOnPreferenceClickListener(preference -> {
|
pref.setOnPreferenceClickListener(preference -> {
|
||||||
OnCancelListener listener = null;
|
TopLevelHighlightMixin highlightMixin = null;
|
||||||
if (fragment instanceof TopLevelSettings
|
if (fragment instanceof TopLevelSettings
|
||||||
&& ActivityEmbeddingUtils.isEmbeddingActivityEnabled(mContext)) {
|
&& ActivityEmbeddingUtils.isEmbeddingActivityEnabled(mContext)) {
|
||||||
// Register the rule for injected apps.
|
// Highlight the preference whenever it's clicked
|
||||||
ActivityEmbeddingRulesController.registerTwoPanePairRuleForSettingsHome(
|
|
||||||
mContext,
|
|
||||||
new ComponentName(tile.getPackageName(), tile.getComponentName()),
|
|
||||||
null /* secondaryIntentAction */,
|
|
||||||
true /* clearTop */);
|
|
||||||
|
|
||||||
// Highlight preference ui.
|
|
||||||
final TopLevelSettings topLevelSettings = (TopLevelSettings) fragment;
|
final TopLevelSettings topLevelSettings = (TopLevelSettings) fragment;
|
||||||
// Highlight the tile immediately whenever it's clicked
|
|
||||||
topLevelSettings.setHighlightPreferenceKey(key);
|
topLevelSettings.setHighlightPreferenceKey(key);
|
||||||
// If the tile allows users to select profile, the pop-op dialog may be
|
highlightMixin = topLevelSettings.getHighlightMixin();
|
||||||
// cancelled and then the previous highlight entry should be restored.
|
|
||||||
listener = dialog -> topLevelSettings.restorePreviousHighlight();
|
|
||||||
}
|
}
|
||||||
launchIntentOrSelectProfile(activity, tile, intent, sourceMetricsCategory,
|
launchIntentOrSelectProfile(activity, tile, intent, sourceMetricsCategory,
|
||||||
listener);
|
highlightMixin);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -223,7 +219,7 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider {
|
|||||||
SettingsEnums.DASHBOARD_SUMMARY)
|
SettingsEnums.DASHBOARD_SUMMARY)
|
||||||
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||||
launchIntentOrSelectProfile(activity, tile, intent, SettingsEnums.DASHBOARD_SUMMARY,
|
launchIntentOrSelectProfile(activity, tile, intent, SettingsEnums.DASHBOARD_SUMMARY,
|
||||||
/* listener= */ null);
|
/* highlightMixin= */ null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DynamicDataObserver createDynamicDataObserver(String method, Uri uri, Preference pref) {
|
private DynamicDataObserver createDynamicDataObserver(String method, Uri uri, Preference pref) {
|
||||||
@@ -438,7 +434,7 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void launchIntentOrSelectProfile(FragmentActivity activity, Tile tile, Intent intent,
|
private void launchIntentOrSelectProfile(FragmentActivity activity, Tile tile, Intent intent,
|
||||||
int sourceMetricCategory, OnCancelListener listener) {
|
int sourceMetricCategory, TopLevelHighlightMixin highlightMixin) {
|
||||||
if (!isIntentResolvable(intent)) {
|
if (!isIntentResolvable(intent)) {
|
||||||
Log.w(TAG, "Cannot resolve intent, skipping. " + intent);
|
Log.w(TAG, "Cannot resolve intent, skipping. " + intent);
|
||||||
return;
|
return;
|
||||||
@@ -469,7 +465,9 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ProfileSelectDialog.show(activity.getSupportFragmentManager(), tile,
|
ProfileSelectDialog.show(activity.getSupportFragmentManager(), tile,
|
||||||
sourceMetricCategory, listener);
|
sourceMetricCategory, /* onShowListener= */ highlightMixin,
|
||||||
|
/* onDismissListener= */ highlightMixin,
|
||||||
|
/* onCancelListener= */ highlightMixin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -21,6 +21,8 @@ import android.content.Context;
|
|||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.DialogInterface.OnCancelListener;
|
import android.content.DialogInterface.OnCancelListener;
|
||||||
import android.content.DialogInterface.OnClickListener;
|
import android.content.DialogInterface.OnClickListener;
|
||||||
|
import android.content.DialogInterface.OnDismissListener;
|
||||||
|
import android.content.DialogInterface.OnShowListener;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
@@ -45,23 +47,30 @@ public class ProfileSelectDialog extends DialogFragment implements OnClickListen
|
|||||||
|
|
||||||
private int mSourceMetricCategory;
|
private int mSourceMetricCategory;
|
||||||
private Tile mSelectedTile;
|
private Tile mSelectedTile;
|
||||||
|
private OnShowListener mOnShowListener;
|
||||||
private OnCancelListener mOnCancelListener;
|
private OnCancelListener mOnCancelListener;
|
||||||
|
private OnDismissListener mOnDismissListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display the profile select dialog, adding the fragment to the given FragmentManager.
|
* Display the profile select dialog, adding the fragment to the given FragmentManager.
|
||||||
* @param manager The FragmentManager this fragment will be added to.
|
* @param manager The FragmentManager this fragment will be added to.
|
||||||
* @param tile The tile for this fragment.
|
* @param tile The tile for this fragment.
|
||||||
* @param sourceMetricCategory The source metric category.
|
* @param sourceMetricCategory The source metric category.
|
||||||
* @param listener The listener listens to the dialog cancelling event.
|
* @param onShowListener The listener listens to the dialog showing event.
|
||||||
|
* @param onDismissListener The listener listens to the dialog dismissing event.
|
||||||
|
* @param onCancelListener The listener listens to the dialog cancelling event.
|
||||||
*/
|
*/
|
||||||
public static void show(FragmentManager manager, Tile tile, int sourceMetricCategory,
|
public static void show(FragmentManager manager, Tile tile, int sourceMetricCategory,
|
||||||
OnCancelListener listener) {
|
OnShowListener onShowListener, OnDismissListener onDismissListener,
|
||||||
|
OnCancelListener onCancelListener) {
|
||||||
final ProfileSelectDialog dialog = new ProfileSelectDialog();
|
final ProfileSelectDialog dialog = new ProfileSelectDialog();
|
||||||
final Bundle args = new Bundle();
|
final Bundle args = new Bundle();
|
||||||
args.putParcelable(ARG_SELECTED_TILE, tile);
|
args.putParcelable(ARG_SELECTED_TILE, tile);
|
||||||
args.putInt(ARG_SOURCE_METRIC_CATEGORY, sourceMetricCategory);
|
args.putInt(ARG_SOURCE_METRIC_CATEGORY, sourceMetricCategory);
|
||||||
dialog.setArguments(args);
|
dialog.setArguments(args);
|
||||||
dialog.mOnCancelListener = listener;
|
dialog.mOnShowListener = onShowListener;
|
||||||
|
dialog.mOnDismissListener = onDismissListener;
|
||||||
|
dialog.mOnCancelListener = onCancelListener;
|
||||||
dialog.show(manager, "select_profile");
|
dialog.show(manager, "select_profile");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,13 +105,31 @@ public class ProfileSelectDialog extends DialogFragment implements OnClickListen
|
|||||||
getActivity().startActivityAsUser(intent, user);
|
getActivity().startActivityAsUser(intent, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
// The fragment shows the dialog within onStart()
|
||||||
|
if (mOnShowListener != null) {
|
||||||
|
mOnShowListener.onShow(getDialog());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCancel(DialogInterface dialog) {
|
public void onCancel(DialogInterface dialog) {
|
||||||
|
super.onCancel(dialog);
|
||||||
if (mOnCancelListener != null) {
|
if (mOnCancelListener != null) {
|
||||||
mOnCancelListener.onCancel(dialog);
|
mOnCancelListener.onCancel(dialog);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDismiss(DialogInterface dialog) {
|
||||||
|
super.onDismiss(dialog);
|
||||||
|
if (mOnDismissListener != null) {
|
||||||
|
mOnDismissListener.onDismiss(dialog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void updateUserHandlesIfNeeded(Context context, Tile tile) {
|
public static void updateUserHandlesIfNeeded(Context context, Tile tile) {
|
||||||
final List<UserHandle> userHandles = tile.userHandle;
|
final List<UserHandle> userHandles = tile.userHandle;
|
||||||
if (tile.userHandle == null || tile.userHandle.size() <= 1) {
|
if (tile.userHandle == null || tile.userHandle.size() <= 1) {
|
||||||
|
@@ -63,6 +63,11 @@ public class TopLevelWallpaperPreferenceController extends BasePreferenceControl
|
|||||||
super.displayPreference(screen);
|
super.displayPreference(screen);
|
||||||
Preference preference = screen.findPreference(getPreferenceKey());
|
Preference preference = screen.findPreference(getPreferenceKey());
|
||||||
preference.setTitle(getTitle());
|
preference.setTitle(getTitle());
|
||||||
|
ActivityEmbeddingRulesController.registerTwoPanePairRuleForSettingsHome(
|
||||||
|
mContext,
|
||||||
|
getComponentName(),
|
||||||
|
null /* secondaryIntentAction */,
|
||||||
|
true /* clearTop */);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
@@ -103,11 +108,6 @@ public class TopLevelWallpaperPreferenceController extends BasePreferenceControl
|
|||||||
mContext)) {
|
mContext)) {
|
||||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||||
}
|
}
|
||||||
ActivityEmbeddingRulesController.registerTwoPanePairRuleForSettingsHome(
|
|
||||||
mContext,
|
|
||||||
intent.getComponent(),
|
|
||||||
null /* secondaryIntentAction */,
|
|
||||||
true /* clearTop */);
|
|
||||||
preference.getContext().startActivity(intent);
|
preference.getContext().startActivity(intent);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -76,7 +76,7 @@ public class SettingsHomepageActivity extends FragmentActivity implements
|
|||||||
public static final String EXTRA_SETTINGS_LARGE_SCREEN_DEEP_LINK_INTENT_DATA =
|
public static final String EXTRA_SETTINGS_LARGE_SCREEN_DEEP_LINK_INTENT_DATA =
|
||||||
"settings_large_screen_deep_link_intent_data";
|
"settings_large_screen_deep_link_intent_data";
|
||||||
|
|
||||||
private static final int DEFAULT_HIGHLIGHT_MENU_KEY = R.string.menu_key_network;
|
static final int DEFAULT_HIGHLIGHT_MENU_KEY = R.string.menu_key_network;
|
||||||
private static final long HOMEPAGE_LOADING_TIMEOUT_MS = 300;
|
private static final long HOMEPAGE_LOADING_TIMEOUT_MS = 300;
|
||||||
|
|
||||||
private TopLevelSettings mMainFragment;
|
private TopLevelSettings mMainFragment;
|
||||||
@@ -94,6 +94,10 @@ public class SettingsHomepageActivity extends FragmentActivity implements
|
|||||||
void onHomepageLoaded();
|
void onHomepageLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private interface FragmentBuilder<T extends Fragment> {
|
||||||
|
T build();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to add a {@link HomepageLoadedListener}. If homepage is already loaded, the listener
|
* Try to add a {@link HomepageLoadedListener}. If homepage is already loaded, the listener
|
||||||
* will not be notified.
|
* will not be notified.
|
||||||
@@ -168,13 +172,15 @@ public class SettingsHomepageActivity extends FragmentActivity implements
|
|||||||
initAvatarView();
|
initAvatarView();
|
||||||
showSuggestionFragment();
|
showSuggestionFragment();
|
||||||
if (FeatureFlagUtils.isEnabled(this, FeatureFlags.CONTEXTUAL_HOME)) {
|
if (FeatureFlagUtils.isEnabled(this, FeatureFlags.CONTEXTUAL_HOME)) {
|
||||||
showFragment(new ContextualCardsFragment(), R.id.contextual_cards_content);
|
showFragment(() -> new ContextualCardsFragment(), R.id.contextual_cards_content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mMainFragment = new TopLevelSettings();
|
mMainFragment = showFragment(() -> {
|
||||||
mMainFragment.getArguments().putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY,
|
final TopLevelSettings fragment = new TopLevelSettings();
|
||||||
getHighlightMenuKey());
|
fragment.getArguments().putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY,
|
||||||
showFragment(mMainFragment, R.id.main_content);
|
getHighlightMenuKey());
|
||||||
|
return fragment;
|
||||||
|
}, R.id.main_content);
|
||||||
|
|
||||||
((FrameLayout) findViewById(R.id.main_content))
|
((FrameLayout) findViewById(R.id.main_content))
|
||||||
.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
|
.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
|
||||||
@@ -260,9 +266,9 @@ public class SettingsHomepageActivity extends FragmentActivity implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void showSuggestionFragment() {
|
private void showSuggestionFragment() {
|
||||||
final Class<? extends Fragment> fragment = FeatureFactory.getFactory(this)
|
final Class<? extends Fragment> fragmentClass = FeatureFactory.getFactory(this)
|
||||||
.getSuggestionFeatureProvider(this).getContextualSuggestionFragment();
|
.getSuggestionFeatureProvider(this).getContextualSuggestionFragment();
|
||||||
if (fragment == null) {
|
if (fragmentClass == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,28 +280,33 @@ public class SettingsHomepageActivity extends FragmentActivity implements
|
|||||||
// Schedule a timer to show the homepage and hide the suggestion on timeout.
|
// Schedule a timer to show the homepage and hide the suggestion on timeout.
|
||||||
mHomepageView.postDelayed(() -> showHomepageWithSuggestion(false),
|
mHomepageView.postDelayed(() -> showHomepageWithSuggestion(false),
|
||||||
HOMEPAGE_LOADING_TIMEOUT_MS);
|
HOMEPAGE_LOADING_TIMEOUT_MS);
|
||||||
try {
|
final FragmentBuilder<?> fragmentBuilder = () -> {
|
||||||
showFragment(fragment.getConstructor().newInstance(), R.id.suggestion_content);
|
try {
|
||||||
if (mIsEmbeddingActivityEnabled) {
|
return fragmentClass.getConstructor().newInstance();
|
||||||
showFragment(fragment.getConstructor().newInstance(),
|
} catch (Exception e) {
|
||||||
R.id.two_pane_suggestion_content);
|
Log.w(TAG, "Cannot show fragment", e);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
return null;
|
||||||
Log.w(TAG, "Cannot show fragment", e);
|
};
|
||||||
|
showFragment(fragmentBuilder, R.id.suggestion_content);
|
||||||
|
if (mIsEmbeddingActivityEnabled) {
|
||||||
|
showFragment(fragmentBuilder, R.id.two_pane_suggestion_content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showFragment(Fragment fragment, int id) {
|
private <T extends Fragment> T showFragment(FragmentBuilder<T> fragmentBuilder, int id) {
|
||||||
final FragmentManager fragmentManager = getSupportFragmentManager();
|
final FragmentManager fragmentManager = getSupportFragmentManager();
|
||||||
final FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
|
final FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
|
||||||
final Fragment showFragment = fragmentManager.findFragmentById(id);
|
T showFragment = (T) fragmentManager.findFragmentById(id);
|
||||||
|
|
||||||
if (showFragment == null) {
|
if (showFragment == null) {
|
||||||
fragmentTransaction.add(id, fragment);
|
showFragment = fragmentBuilder.build();
|
||||||
|
fragmentTransaction.add(id, showFragment);
|
||||||
} else {
|
} else {
|
||||||
fragmentTransaction.show(showFragment);
|
fragmentTransaction.show(showFragment);
|
||||||
}
|
}
|
||||||
fragmentTransaction.commit();
|
fragmentTransaction.commit();
|
||||||
|
return showFragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void launchDeepLinkIntentToRight() {
|
private void launchDeepLinkIntentToRight() {
|
||||||
@@ -363,14 +374,14 @@ public class SettingsHomepageActivity extends FragmentActivity implements
|
|||||||
targetIntent.getAction(),
|
targetIntent.getAction(),
|
||||||
SplitRule.FINISH_ALWAYS,
|
SplitRule.FINISH_ALWAYS,
|
||||||
SplitRule.FINISH_ALWAYS,
|
SplitRule.FINISH_ALWAYS,
|
||||||
true /* clearTop*/);
|
true /* clearTop */);
|
||||||
ActivityEmbeddingRulesController.registerTwoPanePairRule(this,
|
ActivityEmbeddingRulesController.registerTwoPanePairRule(this,
|
||||||
new ComponentName(Settings.class.getPackageName(), Settings.class.getName()),
|
new ComponentName(getApplicationContext(), Settings.class),
|
||||||
targetComponentName,
|
targetComponentName,
|
||||||
targetIntent.getAction(),
|
targetIntent.getAction(),
|
||||||
SplitRule.FINISH_ALWAYS,
|
SplitRule.FINISH_ALWAYS,
|
||||||
SplitRule.FINISH_ALWAYS,
|
SplitRule.FINISH_ALWAYS,
|
||||||
true /* clearTop*/);
|
true /* clearTop */);
|
||||||
startActivity(targetIntent);
|
startActivity(targetIntent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
189
src/com/android/settings/homepage/TopLevelHighlightMixin.java
Normal file
189
src/com/android/settings/homepage/TopLevelHighlightMixin.java
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.homepage;
|
||||||
|
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.fragment.app.FragmentActivity;
|
||||||
|
import androidx.preference.PreferenceScreen;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.android.settings.SettingsActivity;
|
||||||
|
import com.android.settings.widget.HighlightableTopLevelPreferenceAdapter;
|
||||||
|
|
||||||
|
/** A highlight mixin for the top level settings fragment. */
|
||||||
|
public class TopLevelHighlightMixin implements Parcelable, DialogInterface.OnShowListener,
|
||||||
|
DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
|
||||||
|
|
||||||
|
private static final String TAG = "TopLevelHighlightMixin";
|
||||||
|
|
||||||
|
private String mCurrentKey;
|
||||||
|
// Stores the previous key for the profile select dialog cancel event
|
||||||
|
private String mPreviousKey;
|
||||||
|
// Stores the key hidden for the search page presence
|
||||||
|
private String mHiddenKey;
|
||||||
|
private DialogInterface mDialog;
|
||||||
|
private HighlightableTopLevelPreferenceAdapter mTopLevelAdapter;
|
||||||
|
|
||||||
|
public TopLevelHighlightMixin() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public TopLevelHighlightMixin(Parcel source) {
|
||||||
|
mCurrentKey = source.readString();
|
||||||
|
mPreviousKey = source.readString();
|
||||||
|
mHiddenKey = source.readString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
|
dest.writeString(mCurrentKey);
|
||||||
|
dest.writeString(mPreviousKey);
|
||||||
|
dest.writeString(mHiddenKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Creator<TopLevelHighlightMixin> CREATOR = new Creator<>() {
|
||||||
|
@Override
|
||||||
|
public TopLevelHighlightMixin createFromParcel(Parcel source) {
|
||||||
|
return new TopLevelHighlightMixin(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TopLevelHighlightMixin[] newArray(int size) {
|
||||||
|
return new TopLevelHighlightMixin[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onShow(DialogInterface dialog) {
|
||||||
|
mDialog = dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDismiss(DialogInterface dialog) {
|
||||||
|
mDialog = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCancel(DialogInterface dialog) {
|
||||||
|
if (mTopLevelAdapter != null) {
|
||||||
|
mCurrentKey = mPreviousKey;
|
||||||
|
mPreviousKey = null;
|
||||||
|
mTopLevelAdapter.highlightPreference(mCurrentKey, /* scrollNeeded= */ false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RecyclerView.Adapter onCreateAdapter(TopLevelSettings topLevelSettings,
|
||||||
|
PreferenceScreen preferenceScreen) {
|
||||||
|
if (TextUtils.isEmpty(mCurrentKey)) {
|
||||||
|
mCurrentKey = getHighlightPrefKeyFromArguments(topLevelSettings.getArguments());
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d(TAG, "onCreateAdapter, pref key: " + mCurrentKey);
|
||||||
|
mTopLevelAdapter = new HighlightableTopLevelPreferenceAdapter(
|
||||||
|
(SettingsHomepageActivity) topLevelSettings.getActivity(), preferenceScreen,
|
||||||
|
topLevelSettings.getListView(), mCurrentKey);
|
||||||
|
return mTopLevelAdapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reloadHighlightMenuKey(Bundle arguments) {
|
||||||
|
if (mTopLevelAdapter == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ensureDialogDismissed();
|
||||||
|
|
||||||
|
mCurrentKey = getHighlightPrefKeyFromArguments(arguments);
|
||||||
|
Log.d(TAG, "reloadHighlightMenuKey, pref key: " + mCurrentKey);
|
||||||
|
mTopLevelAdapter.highlightPreference(mCurrentKey, /* scrollNeeded= */ true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setHighlightPreferenceKey(String prefKey) {
|
||||||
|
if (mTopLevelAdapter != null) {
|
||||||
|
ensureDialogDismissed();
|
||||||
|
mPreviousKey = mCurrentKey;
|
||||||
|
mCurrentKey = prefKey;
|
||||||
|
mTopLevelAdapter.highlightPreference(prefKey, /* scrollNeeded= */ false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void highlightPreferenceIfNeeded(FragmentActivity activity) {
|
||||||
|
if (mTopLevelAdapter != null) {
|
||||||
|
mTopLevelAdapter.requestHighlight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setMenuHighlightShowed(boolean show) {
|
||||||
|
if (mTopLevelAdapter == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ensureDialogDismissed();
|
||||||
|
|
||||||
|
if (show) {
|
||||||
|
mCurrentKey = mHiddenKey;
|
||||||
|
mHiddenKey = null;
|
||||||
|
} else {
|
||||||
|
if (mHiddenKey == null) {
|
||||||
|
mHiddenKey = mCurrentKey;
|
||||||
|
}
|
||||||
|
mCurrentKey = null;
|
||||||
|
}
|
||||||
|
mTopLevelAdapter.highlightPreference(mCurrentKey, /* scrollNeeded= */ show);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setHighlightMenuKey(String menuKey, boolean scrollNeeded) {
|
||||||
|
if (mTopLevelAdapter == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ensureDialogDismissed();
|
||||||
|
|
||||||
|
final String prefKey = HighlightableMenu.lookupPreferenceKey(menuKey);
|
||||||
|
if (TextUtils.isEmpty(prefKey)) {
|
||||||
|
Log.e(TAG, "Invalid highlight menu key: " + menuKey);
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "Menu key: " + menuKey);
|
||||||
|
mCurrentKey = prefKey;
|
||||||
|
mTopLevelAdapter.highlightPreference(prefKey, scrollNeeded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getHighlightPrefKeyFromArguments(Bundle arguments) {
|
||||||
|
final String menuKey = arguments.getString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY);
|
||||||
|
final String prefKey = HighlightableMenu.lookupPreferenceKey(menuKey);
|
||||||
|
if (TextUtils.isEmpty(prefKey)) {
|
||||||
|
Log.e(TAG, "Invalid highlight menu key: " + menuKey);
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "Menu key: " + menuKey);
|
||||||
|
}
|
||||||
|
return prefKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ensureDialogDismissed() {
|
||||||
|
if (mDialog != null) {
|
||||||
|
onCancel(mDialog);
|
||||||
|
mDialog.dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -25,7 +25,6 @@ import android.content.res.Configuration;
|
|||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
@@ -34,7 +33,6 @@ import androidx.preference.PreferenceScreen;
|
|||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.SettingsActivity;
|
|
||||||
import com.android.settings.Utils;
|
import com.android.settings.Utils;
|
||||||
import com.android.settings.activityembedding.ActivityEmbeddingRulesController;
|
import com.android.settings.activityembedding.ActivityEmbeddingRulesController;
|
||||||
import com.android.settings.activityembedding.ActivityEmbeddingUtils;
|
import com.android.settings.activityembedding.ActivityEmbeddingUtils;
|
||||||
@@ -42,7 +40,6 @@ import com.android.settings.core.SubSettingLauncher;
|
|||||||
import com.android.settings.dashboard.DashboardFragment;
|
import com.android.settings.dashboard.DashboardFragment;
|
||||||
import com.android.settings.search.BaseSearchIndexProvider;
|
import com.android.settings.search.BaseSearchIndexProvider;
|
||||||
import com.android.settings.support.SupportPreferenceController;
|
import com.android.settings.support.SupportPreferenceController;
|
||||||
import com.android.settings.widget.HighlightableTopLevelPreferenceAdapter;
|
|
||||||
import com.android.settings.widget.HomepagePreference;
|
import com.android.settings.widget.HomepagePreference;
|
||||||
import com.android.settingslib.core.instrumentation.Instrumentable;
|
import com.android.settingslib.core.instrumentation.Instrumentable;
|
||||||
import com.android.settingslib.drawer.Tile;
|
import com.android.settingslib.drawer.Tile;
|
||||||
@@ -53,13 +50,10 @@ public class TopLevelSettings extends DashboardFragment implements
|
|||||||
PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
|
PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
|
||||||
|
|
||||||
private static final String TAG = "TopLevelSettings";
|
private static final String TAG = "TopLevelSettings";
|
||||||
private static final String SAVED_HIGHLIGHTED_PREF = "highlighted_pref";
|
private static final String SAVED_HIGHLIGHT_MIXIN = "highlight_mixin";
|
||||||
private static final String SAVED_CACHED_PREF = "cached_pref";
|
private static final String PREF_KEY_SUPPORT = "top_level_support";
|
||||||
|
|
||||||
private HighlightableTopLevelPreferenceAdapter mTopLevelAdapter;
|
private TopLevelHighlightMixin mHighlightMixin;
|
||||||
|
|
||||||
private String mHighlightedPreferenceKey;
|
|
||||||
private String mCachedPreferenceKey;
|
|
||||||
|
|
||||||
public TopLevelSettings() {
|
public TopLevelSettings() {
|
||||||
final Bundle args = new Bundle();
|
final Bundle args = new Bundle();
|
||||||
@@ -127,17 +121,35 @@ public class TopLevelSettings extends DashboardFragment implements
|
|||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle icicle) {
|
public void onCreate(Bundle icicle) {
|
||||||
super.onCreate(icicle);
|
super.onCreate(icicle);
|
||||||
if (icicle != null) {
|
if (!ActivityEmbeddingUtils.isEmbeddingActivityEnabled(getContext())) {
|
||||||
mHighlightedPreferenceKey = icicle.getString(SAVED_HIGHLIGHTED_PREF);
|
return;
|
||||||
mCachedPreferenceKey = icicle.getString(SAVED_CACHED_PREF);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (icicle != null) {
|
||||||
|
mHighlightMixin = icicle.getParcelable(SAVED_HIGHLIGHT_MIXIN);
|
||||||
|
}
|
||||||
|
if (mHighlightMixin == null) {
|
||||||
|
mHighlightMixin = new TopLevelHighlightMixin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
// Set default highlight menu key for 1-pane homepage since it will show the placeholder
|
||||||
|
// page once changing back to 2-pane.
|
||||||
|
if (!ActivityEmbeddingUtils.isTwoPaneResolution(getActivity())) {
|
||||||
|
setHighlightMenuKey(getString(SettingsHomepageActivity.DEFAULT_HIGHLIGHT_MENU_KEY),
|
||||||
|
/* scrollNeeded= */ false);
|
||||||
|
}
|
||||||
|
super.onStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSaveInstanceState(Bundle outState) {
|
public void onSaveInstanceState(Bundle outState) {
|
||||||
super.onSaveInstanceState(outState);
|
super.onSaveInstanceState(outState);
|
||||||
outState.putString(SAVED_HIGHLIGHTED_PREF, mHighlightedPreferenceKey);
|
if (mHighlightMixin != null) {
|
||||||
outState.putString(SAVED_CACHED_PREF, mCachedPreferenceKey);
|
outState.putParcelable(SAVED_HIGHLIGHT_MIXIN, mHighlightMixin);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -170,58 +182,35 @@ public class TopLevelSettings extends DashboardFragment implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void highlightPreferenceIfNeeded() {
|
public void highlightPreferenceIfNeeded() {
|
||||||
if (mTopLevelAdapter != null) {
|
if (mHighlightMixin != null) {
|
||||||
mTopLevelAdapter.requestHighlight();
|
mHighlightMixin.highlightPreferenceIfNeeded(getActivity());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns a {@link TopLevelHighlightMixin} that performs highlighting */
|
||||||
|
public TopLevelHighlightMixin getHighlightMixin() {
|
||||||
|
return mHighlightMixin;
|
||||||
|
}
|
||||||
|
|
||||||
/** Highlight a preference with specified preference key */
|
/** Highlight a preference with specified preference key */
|
||||||
public void setHighlightPreferenceKey(String prefKey) {
|
public void setHighlightPreferenceKey(String prefKey) {
|
||||||
if (mTopLevelAdapter != null) {
|
// Skip Tips & support since it's full screen
|
||||||
mCachedPreferenceKey = null;
|
if (mHighlightMixin != null && !TextUtils.equals(prefKey, PREF_KEY_SUPPORT)) {
|
||||||
mHighlightedPreferenceKey = prefKey;
|
mHighlightMixin.setHighlightPreferenceKey(prefKey);
|
||||||
mTopLevelAdapter.highlightPreference(prefKey, /* scrollNeeded= */ false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Highlight the previous preference */
|
/** Show/hide the highlight on the menu entry for the search page presence */
|
||||||
public void restorePreviousHighlight() {
|
|
||||||
if (mTopLevelAdapter != null) {
|
|
||||||
mTopLevelAdapter.restorePreviousHighlight();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Show/hide the highlight on the menu entry */
|
|
||||||
public void setMenuHighlightShowed(boolean show) {
|
public void setMenuHighlightShowed(boolean show) {
|
||||||
if (mTopLevelAdapter == null) {
|
if (mHighlightMixin != null) {
|
||||||
return;
|
mHighlightMixin.setMenuHighlightShowed(show);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (show) {
|
|
||||||
mHighlightedPreferenceKey = mCachedPreferenceKey;
|
|
||||||
mCachedPreferenceKey = null;
|
|
||||||
} else {
|
|
||||||
if (mCachedPreferenceKey == null) {
|
|
||||||
mCachedPreferenceKey = mHighlightedPreferenceKey;
|
|
||||||
}
|
|
||||||
mHighlightedPreferenceKey = null;
|
|
||||||
}
|
|
||||||
mTopLevelAdapter.highlightPreference(mHighlightedPreferenceKey, /* scrollNeeded= */ show);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Highlight and scroll to a preference with specified menu key */
|
/** Highlight and scroll to a preference with specified menu key */
|
||||||
public void setHighlightMenuKey(String menuKey) {
|
public void setHighlightMenuKey(String menuKey, boolean scrollNeeded) {
|
||||||
if (mTopLevelAdapter == null) {
|
if (mHighlightMixin != null) {
|
||||||
return;
|
mHighlightMixin.setHighlightMenuKey(menuKey, scrollNeeded);
|
||||||
}
|
|
||||||
|
|
||||||
final String prefKey = HighlightableMenu.lookupPreferenceKey(menuKey);
|
|
||||||
if (TextUtils.isEmpty(prefKey)) {
|
|
||||||
Log.e(TAG, "Invalid highlight menu key: " + menuKey);
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Menu key: " + menuKey);
|
|
||||||
mHighlightedPreferenceKey = prefKey;
|
|
||||||
mTopLevelAdapter.highlightPreference(prefKey, /* scrollNeeded= */ true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,16 +226,7 @@ public class TopLevelSettings extends DashboardFragment implements
|
|||||||
|| !(getActivity() instanceof SettingsHomepageActivity)) {
|
|| !(getActivity() instanceof SettingsHomepageActivity)) {
|
||||||
return super.onCreateAdapter(preferenceScreen);
|
return super.onCreateAdapter(preferenceScreen);
|
||||||
}
|
}
|
||||||
|
return mHighlightMixin.onCreateAdapter(this, preferenceScreen);
|
||||||
if (TextUtils.isEmpty(mHighlightedPreferenceKey)) {
|
|
||||||
mHighlightedPreferenceKey = getHighlightPrefKeyFromArguments();
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.d(TAG, "onCreateAdapter, pref key: " + mHighlightedPreferenceKey);
|
|
||||||
mTopLevelAdapter = new HighlightableTopLevelPreferenceAdapter(
|
|
||||||
(SettingsHomepageActivity) getActivity(), preferenceScreen, getListView(),
|
|
||||||
mHighlightedPreferenceKey);
|
|
||||||
return mTopLevelAdapter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -255,25 +235,9 @@ public class TopLevelSettings extends DashboardFragment implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
void reloadHighlightMenuKey() {
|
void reloadHighlightMenuKey() {
|
||||||
if (mTopLevelAdapter == null) {
|
if (mHighlightMixin != null) {
|
||||||
return;
|
mHighlightMixin.reloadHighlightMenuKey(getArguments());
|
||||||
}
|
}
|
||||||
|
|
||||||
mHighlightedPreferenceKey = getHighlightPrefKeyFromArguments();
|
|
||||||
Log.d(TAG, "reloadHighlightMenuKey, pref key: " + mHighlightedPreferenceKey);
|
|
||||||
mTopLevelAdapter.highlightPreference(mHighlightedPreferenceKey, /* scrollNeeded= */ true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getHighlightPrefKeyFromArguments() {
|
|
||||||
final Bundle arguments = getArguments();
|
|
||||||
final String menuKey = arguments.getString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY);
|
|
||||||
final String prefKey = HighlightableMenu.lookupPreferenceKey(menuKey);
|
|
||||||
if (TextUtils.isEmpty(prefKey)) {
|
|
||||||
Log.e(TAG, "Invalid highlight menu key: " + menuKey);
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Menu key: " + menuKey);
|
|
||||||
}
|
|
||||||
return prefKey;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
||||||
|
@@ -109,7 +109,8 @@ public class SearchResultTrampoline extends Activity {
|
|||||||
final SettingsHomepageActivity homeActivity =
|
final SettingsHomepageActivity homeActivity =
|
||||||
((SettingsApplication) getApplicationContext()).getHomeActivity();
|
((SettingsApplication) getApplicationContext()).getHomeActivity();
|
||||||
if (homeActivity != null) {
|
if (homeActivity != null) {
|
||||||
homeActivity.getMainFragment().setHighlightMenuKey(highlightMenuKey);
|
homeActivity.getMainFragment().setHighlightMenuKey(highlightMenuKey,
|
||||||
|
/* scrollNeeded= */ true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Two-pane case
|
// Two-pane case
|
||||||
|
@@ -20,6 +20,7 @@ import android.content.Context;
|
|||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.util.SparseArray;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
@@ -59,17 +60,18 @@ public class HighlightableTopLevelPreferenceAdapter extends PreferenceGroupAdapt
|
|||||||
private final int mNormalBackgroundRes;
|
private final int mNormalBackgroundRes;
|
||||||
private final int mHighlightBackgroundRes;
|
private final int mHighlightBackgroundRes;
|
||||||
private String mHighlightKey;
|
private String mHighlightKey;
|
||||||
private String mPreviousHighlightKey;
|
|
||||||
private int mHighlightPosition = RecyclerView.NO_POSITION;
|
private int mHighlightPosition = RecyclerView.NO_POSITION;
|
||||||
private int mScrollPosition = RecyclerView.NO_POSITION;
|
private int mScrollPosition = RecyclerView.NO_POSITION;
|
||||||
private boolean mHighlightNeeded;
|
private boolean mHighlightNeeded;
|
||||||
private boolean mScrolled;
|
private boolean mScrolled;
|
||||||
|
private SparseArray<PreferenceViewHolder> mViewHolders;
|
||||||
|
|
||||||
public HighlightableTopLevelPreferenceAdapter(SettingsHomepageActivity homepageActivity,
|
public HighlightableTopLevelPreferenceAdapter(SettingsHomepageActivity homepageActivity,
|
||||||
PreferenceGroup preferenceGroup, RecyclerView recyclerView, String key) {
|
PreferenceGroup preferenceGroup, RecyclerView recyclerView, String key) {
|
||||||
super(preferenceGroup);
|
super(preferenceGroup);
|
||||||
mRecyclerView = recyclerView;
|
mRecyclerView = recyclerView;
|
||||||
mHighlightKey = key;
|
mHighlightKey = key;
|
||||||
|
mViewHolders = new SparseArray<>();
|
||||||
mContext = preferenceGroup.getContext();
|
mContext = preferenceGroup.getContext();
|
||||||
mHomepageActivity = homepageActivity;
|
mHomepageActivity = homepageActivity;
|
||||||
final TypedValue outValue = new TypedValue();
|
final TypedValue outValue = new TypedValue();
|
||||||
@@ -92,6 +94,7 @@ public class HighlightableTopLevelPreferenceAdapter extends PreferenceGroupAdapt
|
|||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(PreferenceViewHolder holder, int position) {
|
public void onBindViewHolder(PreferenceViewHolder holder, int position) {
|
||||||
super.onBindViewHolder(holder, position);
|
super.onBindViewHolder(holder, position);
|
||||||
|
mViewHolders.put(position, holder);
|
||||||
updateBackground(holder, position);
|
updateBackground(holder, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,9 +123,9 @@ public class HighlightableTopLevelPreferenceAdapter extends PreferenceGroupAdapt
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final int previousPosition = mHighlightPosition;
|
||||||
if (TextUtils.isEmpty(mHighlightKey)) {
|
if (TextUtils.isEmpty(mHighlightKey)) {
|
||||||
// De-highlight previous preference.
|
// De-highlight previous preference.
|
||||||
final int previousPosition = mHighlightPosition;
|
|
||||||
mHighlightPosition = RecyclerView.NO_POSITION;
|
mHighlightPosition = RecyclerView.NO_POSITION;
|
||||||
mScrolled = true;
|
mScrolled = true;
|
||||||
if (previousPosition >= 0) {
|
if (previousPosition >= 0) {
|
||||||
@@ -145,10 +148,14 @@ public class HighlightableTopLevelPreferenceAdapter extends PreferenceGroupAdapt
|
|||||||
|
|
||||||
// Turn on/off highlight when screen split mode is changed.
|
// Turn on/off highlight when screen split mode is changed.
|
||||||
if (highlightNeeded != mHighlightNeeded) {
|
if (highlightNeeded != mHighlightNeeded) {
|
||||||
Log.d(TAG, "Highlight change needed: " + highlightNeeded);
|
Log.d(TAG, "Highlight needed change: " + highlightNeeded);
|
||||||
mHighlightNeeded = highlightNeeded;
|
mHighlightNeeded = highlightNeeded;
|
||||||
mHighlightPosition = position;
|
mHighlightPosition = position;
|
||||||
notifyItemChanged(position);
|
notifyItemChanged(position);
|
||||||
|
if (!highlightNeeded) {
|
||||||
|
// De-highlight to prevent a flicker
|
||||||
|
removeHighlightAt(previousPosition);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,7 +163,6 @@ public class HighlightableTopLevelPreferenceAdapter extends PreferenceGroupAdapt
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int previousPosition = mHighlightPosition;
|
|
||||||
mHighlightPosition = position;
|
mHighlightPosition = position;
|
||||||
Log.d(TAG, "Request highlight position " + position);
|
Log.d(TAG, "Request highlight position " + position);
|
||||||
Log.d(TAG, "Is highlight needed: " + highlightNeeded);
|
Log.d(TAG, "Is highlight needed: " + highlightNeeded);
|
||||||
@@ -178,20 +184,11 @@ public class HighlightableTopLevelPreferenceAdapter extends PreferenceGroupAdapt
|
|||||||
* preference is clicked.
|
* preference is clicked.
|
||||||
*/
|
*/
|
||||||
public void highlightPreference(String key, boolean scrollNeeded) {
|
public void highlightPreference(String key, boolean scrollNeeded) {
|
||||||
mPreviousHighlightKey = mHighlightKey;
|
|
||||||
mHighlightKey = key;
|
mHighlightKey = key;
|
||||||
mScrolled = !scrollNeeded;
|
mScrolled = !scrollNeeded;
|
||||||
requestHighlight();
|
requestHighlight();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* A function that restores the previous highlighted setting.
|
|
||||||
*/
|
|
||||||
public void restorePreviousHighlight() {
|
|
||||||
mHighlightKey = mPreviousHighlightKey;
|
|
||||||
requestHighlight();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onHomepageLoaded() {
|
public void onHomepageLoaded() {
|
||||||
scroll();
|
scroll();
|
||||||
@@ -224,6 +221,17 @@ public class HighlightableTopLevelPreferenceAdapter extends PreferenceGroupAdapt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void removeHighlightAt(int position) {
|
||||||
|
if (position >= 0) {
|
||||||
|
// De-highlight the existing preference view holder at an early stage
|
||||||
|
final PreferenceViewHolder holder = mViewHolders.get(position);
|
||||||
|
if (holder != null) {
|
||||||
|
removeHighlightBackground(holder);
|
||||||
|
}
|
||||||
|
notifyItemChanged(position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void addHighlightBackground(PreferenceViewHolder holder) {
|
private void addHighlightBackground(PreferenceViewHolder holder) {
|
||||||
final View v = holder.itemView;
|
final View v = holder.itemView;
|
||||||
v.setBackgroundResource(mHighlightBackgroundRes);
|
v.setBackgroundResource(mHighlightBackgroundRes);
|
||||||
|
Reference in New Issue
Block a user