From c1457323d271309d5d1955743cd806417c84b9d6 Mon Sep 17 00:00:00 2001 From: Fabrice Di Meglio Date: Fri, 4 Apr 2014 19:07:50 -0700 Subject: [PATCH] Add support for saving and using the Preference's key value - modify the SQlite data model - update Index code for managing the key value - pass the key when launching a Fragment or and Activity - implement a small animation for highlighting the Preference from a Search result Change-Id: I617643a4e5e3b752ece8f45ce7d5429037e479da --- .../android/settings/SettingsActivity.java | 6 +++ .../settings/SettingsPreferenceFragment.java | 45 +++++++++++++++++++ .../dashboard/SearchResultsSummary.java | 18 +++++--- src/com/android/settings/search/Index.java | 45 +++++++++++++------ .../settings/search/IndexDatabaseHelper.java | 5 ++- 5 files changed, 100 insertions(+), 19 deletions(-) diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java index 7cdf78176a0..612869085a2 100644 --- a/src/com/android/settings/SettingsActivity.java +++ b/src/com/android/settings/SettingsActivity.java @@ -145,6 +145,11 @@ public class SettingsActivity extends Activity */ public static final String EXTRA_SHOW_FRAGMENT_ARGUMENTS = ":settings:show_fragment_args"; + /** + * Fragment "key" argument passed thru {@link #EXTRA_SHOW_FRAGMENT_ARGUMENTS} + */ + public static final String EXTRA_FRAGMENT_ARG_KEY = ":settings:fragment_args_key"; + /** * When starting this activity, the invoking Intent can contain this extra * boolean that the header list should not be displayed. This is most often @@ -461,6 +466,7 @@ public class SettingsActivity extends Activity final String initialTitle = getIntent().getStringExtra(EXTRA_SHOW_FRAGMENT_TITLE); mInitialTitle = (initialTitle != null) ? initialTitle : getTitle(); setTitle(mInitialTitle); + switchToFragment( initialFragmentName, initialArguments, true, false, mInitialTitle, false); } else { diff --git a/src/com/android/settings/SettingsPreferenceFragment.java b/src/com/android/settings/SettingsPreferenceFragment.java index 35893ffaf03..d5751531e65 100644 --- a/src/com/android/settings/SettingsPreferenceFragment.java +++ b/src/com/android/settings/SettingsPreferenceFragment.java @@ -26,12 +26,15 @@ import android.content.pm.PackageManager; import android.os.Bundle; import android.preference.Preference; import android.preference.PreferenceFragment; +import android.preference.PreferenceGroup; +import android.preference.PreferenceGroupAdapter; import android.text.TextUtils; import android.util.Log; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.widget.Button; +import android.widget.ListAdapter; /** * Base class for Settings fragments, with some helper functions and dialog management. @@ -41,6 +44,7 @@ public class SettingsPreferenceFragment extends PreferenceFragment implements Di private static final String TAG = "SettingsPreferenceFragment"; private static final int MENU_HELP = Menu.FIRST + 100; + private static final int HIGHLIGHT_DURATION_MILLIS = 750; private SettingsDialogFragment mDialogFragment; @@ -66,6 +70,47 @@ public class SettingsPreferenceFragment extends PreferenceFragment implements Di if (!TextUtils.isEmpty(mHelpUrl)) { setHasOptionsMenu(true); } + + final Bundle args = getArguments(); + if (args != null) { + final String key = args.getString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY); + final int position = findPositionFromKey(getPreferenceScreen(), key); + if (position >= 0) { + final ListAdapter adapter = getListView().getAdapter(); + if (adapter instanceof PreferenceGroupAdapter) { + ((PreferenceGroupAdapter) adapter).setActivated(position); + + getListView().postDelayed(new Runnable() { + @Override + public void run() { + ((PreferenceGroupAdapter) adapter).setActivated(-1); + ((PreferenceGroupAdapter) adapter).notifyDataSetChanged(); + } + }, HIGHLIGHT_DURATION_MILLIS); + } + } + } + } + + private int findPositionFromKey(PreferenceGroup group, String key) { + if (group != null) { + int count = group.getPreferenceCount(); + for (int n = 0; n < count; n++) { + final Preference preference = group.getPreference(n); + final String preferenceKey = preference.getKey(); + if (preferenceKey != null && preferenceKey.equals(key)) { + return n; + } + if (preference instanceof PreferenceGroup) { + PreferenceGroup nestedGroup = (PreferenceGroup) preference; + final int nestedPosition = findPositionFromKey(nestedGroup, key); + if (nestedPosition >= 0) { + return n + 1 + nestedPosition; + } + } + } + } + return -1; } protected void removePreference(String key) { diff --git a/src/com/android/settings/dashboard/SearchResultsSummary.java b/src/com/android/settings/dashboard/SearchResultsSummary.java index 706ae0f5216..22326a67b5a 100644 --- a/src/com/android/settings/dashboard/SearchResultsSummary.java +++ b/src/com/android/settings/dashboard/SearchResultsSummary.java @@ -109,15 +109,18 @@ public class SearchResultsSummary extends Fragment { final String className = cursor.getString(Index.COLUMN_INDEX_CLASS_NAME); final String screenTitle = cursor.getString(Index.COLUMN_INDEX_SCREEN_TITLE); - final String action = cursor.getString(Index.COLUMN_INDEX_INTENT_ACTION); + final String key = cursor.getString(Index.COLUMN_INDEX_KEY); final SettingsActivity sa = (SettingsActivity) getActivity(); sa.needToRevertToInitialFragment(); if (TextUtils.isEmpty(action)) { - sa.startWithFragment(className, null, null, 0, screenTitle); + Bundle args = new Bundle(); + args.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, key); + + sa.startWithFragment(className, args, null, 0, screenTitle); } else { final Intent intent = new Intent(action); @@ -130,6 +133,7 @@ public class SearchResultsSummary extends Fragment { new ComponentName(targetPackage, targetClass); intent.setComponent(component); } + intent.putExtra(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, key); sa.startActivity(intent); } @@ -194,21 +198,23 @@ public class SearchResultsSummary extends Fragment { } private static class SearchResult { + public Context context; public String title; public String summaryOn; public String summaryOff; public String entries; public int iconResId; - public Context context; + public String key; public SearchResult(Context context, String title, String summaryOn, String summaryOff, - String entries, int iconResId) { + String entries, int iconResId, String key) { this.context = context; this.title = title; this.summaryOn = summaryOn; this.summaryOff = summaryOff; this.entries = entries; this.iconResId = iconResId; + this.key = key; } } @@ -263,6 +269,8 @@ public class SearchResultsSummary extends Fragment { Index.COLUMN_INDEX_CLASS_NAME); final String packageName = mCursor.getString( Index.COLUMN_INDEX_INTENT_ACTION_TARGET_PACKAGE); + final String key = mCursor.getString( + Index.COLUMN_INDEX_KEY); Context packageContext; if (TextUtils.isEmpty(className) && !TextUtils.isEmpty(packageName)) { @@ -284,7 +292,7 @@ public class SearchResultsSummary extends Fragment { R.drawable.empty_icon : Integer.parseInt(iconResStr); return new SearchResult(packageContext, title, summaryOn, summaryOff, - entries, iconResId); + entries, iconResId, key); } return null; } diff --git a/src/com/android/settings/search/Index.java b/src/com/android/settings/search/Index.java index 987539b7bc3..138c896d4b9 100644 --- a/src/com/android/settings/search/Index.java +++ b/src/com/android/settings/search/Index.java @@ -71,6 +71,7 @@ public class Index { public static final int COLUMN_INDEX_INTENT_ACTION_TARGET_PACKAGE = 12; public static final int COLUMN_INDEX_INTENT_ACTION_TARGET_CLASS = 13; public static final int COLUMN_INDEX_ENABLED = 14; + public static final int COLUMN_INDEX_KEY = 15; // If you change the order of columns here, you SHOULD change the COLUMN_INDEX_XXX values private static final String[] SELECT_COLUMNS = new String[] { @@ -87,7 +88,9 @@ public class Index { IndexColumns.ICON, // 10 IndexColumns.INTENT_ACTION, // 11 IndexColumns.INTENT_TARGET_PACKAGE, // 12 - IndexColumns.INTENT_TARGET_CLASS // 13 + IndexColumns.INTENT_TARGET_CLASS, // 13 + IndexColumns.ENABLED, // 14 + IndexColumns.DATA_KEY_REF // 15 }; private static final String[] MATCH_COLUMNS = { @@ -375,6 +378,8 @@ public class Index { final String targetPackage = cursor.getString(12); final String targetClass = cursor.getString(13); + final String key = cursor.getString(15); + SearchIndexableRaw data = new SearchIndexableRaw(packageContext); data.rank = rank; data.title = title; @@ -391,6 +396,7 @@ public class Index { data.intentAction = action; data.intentTargetPackage = targetPackage; data.intentTargetClass = targetClass; + data.key = key; addIndexableData(data); } @@ -503,12 +509,13 @@ public class Index { String title = getDataTitle(context, attrs); String summary = getDataSummary(context, attrs); String keywords = getDataKeywords(context, attrs); + String key = getDataKey(context, attrs); // Insert rows for the main PreferenceScreen node. Rewrite the data for removing // hyphens. updateOneRowWithFilteredData(database, localeStr, title, summary, null, null, - null, null, fragmentName, screenTitle, iconResId, rank, keywords, - intentAction, intentTargetPackage, intentTargetClass, true); + null, null, fragmentName, screenTitle, iconResId, rank, + keywords, intentAction, intentTargetPackage, intentTargetClass, true, key); while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { @@ -520,6 +527,7 @@ public class Index { title = getDataTitle(context, attrs); keywords = getDataKeywords(context, attrs); + key = getDataKey(context, attrs); if (!nodeName.equals(NODE_NAME_CHECK_BOX_PREFERENCE)) { summary = getDataSummary(context, attrs); @@ -537,15 +545,17 @@ public class Index { // Insert rows for the child nodes of PreferenceScreen updateOneRowWithFilteredData(database, localeStr, title, summary, null, entries, - switchOn, switchOff, fragmentName, screenTitle, iconResId, rank, keywords, - intentAction, intentTargetPackage, intentTargetClass, true); - } else if (nodeName.equals(NODE_NAME_CHECK_BOX_PREFERENCE)) { + switchOn, switchOff, fragmentName, screenTitle, iconResId, rank, + keywords, intentAction, intentTargetPackage, intentTargetClass, + true, key); + } else { final String summaryOn = getDataSummaryOn(context, attrs); final String summaryOff = getDataSummaryOff(context, attrs); updateOneRowWithFilteredData(database, localeStr, title, summaryOn, summaryOff, - null, null, null, fragmentName, screenTitle, iconResId, rank, keywords, - intentAction, intentTargetPackage, intentTargetClass, true); + null, null, null, fragmentName, screenTitle, iconResId, rank, + keywords, intentAction, intentTargetPackage, intentTargetClass, + true, key); } } @@ -580,7 +590,8 @@ public class Index { raw.intentAction, raw.intentTargetPackage, raw.intentTargetClass, - raw.enabled); + raw.enabled, + raw.key); } private void indexFromLocalProvider(SQLiteDatabase database, String localeStr, @@ -619,7 +630,8 @@ public class Index { raw.intentAction, raw.intentTargetPackage, raw.intentTargetClass, - raw.enabled); + raw.enabled, + raw.key); } } @@ -657,7 +669,7 @@ public class Index { String switchOn, String switchOff, String className, String screenTitle, int iconResId, int rank, String keywords, String intentAction, String intentTargetPackage, String intentTargetClass, - boolean enabled) { + boolean enabled, String key) { String updatedTitle; if (title != null) { @@ -706,7 +718,7 @@ public class Index { updatedSummaryOff, normalizedSummaryOff, entries, updatedSwitchOn, normalizedSwitchOn, updatedSwitchOff, normalizedSwitchOff, className, screenTitle, iconResId, - rank, keywords, intentAction, intentTargetPackage, intentTargetClass, enabled); + rank, keywords, intentAction, intentTargetPackage, intentTargetClass, enabled, key); } private void updateOneRow(SQLiteDatabase database, String locale, @@ -717,7 +729,7 @@ public class Index { String updatedSwitchOff, String normalizedSwitchOff, String className, String screenTitle, int iconResId, int rank, String keywords, String intentAction, String intentTargetPackage, String intentTargetClass, - boolean enabled) { + boolean enabled, String key) { if (TextUtils.isEmpty(updatedTitle)) { return; @@ -746,10 +758,17 @@ public class Index { values.put(IndexColumns.INTENT_TARGET_CLASS, intentTargetClass); values.put(IndexColumns.ICON, iconResId); values.put(IndexColumns.ENABLED, enabled); + values.put(IndexColumns.DATA_KEY_REF, key); database.replaceOrThrow(Tables.TABLE_PREFS_INDEX, null, values); } + private String getDataKey(Context context, AttributeSet attrs) { + return getData(context, attrs, + com.android.internal.R.styleable.Preference, + com.android.internal.R.styleable.Preference_key); + } + private String getDataTitle(Context context, AttributeSet attrs) { return getData(context, attrs, com.android.internal.R.styleable.Preference, diff --git a/src/com/android/settings/search/IndexDatabaseHelper.java b/src/com/android/settings/search/IndexDatabaseHelper.java index bd035c37e18..bc827f47dd4 100644 --- a/src/com/android/settings/search/IndexDatabaseHelper.java +++ b/src/com/android/settings/search/IndexDatabaseHelper.java @@ -28,7 +28,7 @@ public class IndexDatabaseHelper extends SQLiteOpenHelper { private static final String TAG = "IndexDatabaseHelper"; private static final String DATABASE_NAME = "search_index.db"; - private static final int DATABASE_VERSION = 106; + private static final int DATABASE_VERSION = 107; public interface Tables { public static final String TABLE_PREFS_INDEX = "prefs_index"; @@ -58,6 +58,7 @@ public class IndexDatabaseHelper extends SQLiteOpenHelper { public static final String INTENT_TARGET_CLASS = "intent_target_class"; public static final String ICON = "icon"; public static final String ENABLED = "enabled"; + public static final String DATA_KEY_REF = "data_key_reference"; } public interface MetaColumns { @@ -108,6 +109,8 @@ public class IndexDatabaseHelper extends SQLiteOpenHelper { IndexColumns.INTENT_TARGET_CLASS + ", " + IndexColumns.ENABLED + + ", " + + IndexColumns.DATA_KEY_REF + ");"; private static final String CREATE_META_TABLE =