From b61cf51d850d37a4d82b93b8ee0d190930421a46 Mon Sep 17 00:00:00 2001 From: Amith Yamasani Date: Sun, 12 Sep 2010 08:17:50 -0700 Subject: Breadcrumbs in the action bar for navigating up one level and showing current title. Change-Id: I595e06549b888bd67c6dddd599a4cc77416c3a41 --- AndroidManifest.xml | 2 +- res/drawable-hdpi/nav_divider.png | Bin 0 -> 1012 bytes res/drawable-mdpi/nav_divider.png | Bin 0 -> 2846 bytes res/layout/settings_actionbar.xml | 64 ++++++++ src/com/android/settings/Settings.java | 172 +++++++++++++++++---- .../settings/SettingsPreferenceFragment.java | 6 +- 6 files changed, 211 insertions(+), 33 deletions(-) create mode 100644 res/drawable-hdpi/nav_divider.png create mode 100644 res/drawable-mdpi/nav_divider.png create mode 100644 res/layout/settings_actionbar.xml diff --git a/AndroidManifest.xml b/AndroidManifest.xml index e93cb2e..b6a422e 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -49,7 +49,7 @@ + android:theme="@android:style/Theme.Holo"> diff --git a/res/drawable-hdpi/nav_divider.png b/res/drawable-hdpi/nav_divider.png new file mode 100644 index 0000000..7ca3e61 Binary files /dev/null and b/res/drawable-hdpi/nav_divider.png differ diff --git a/res/drawable-mdpi/nav_divider.png b/res/drawable-mdpi/nav_divider.png new file mode 100644 index 0000000..c9413d7 Binary files /dev/null and b/res/drawable-mdpi/nav_divider.png differ diff --git a/res/layout/settings_actionbar.xml b/res/layout/settings_actionbar.xml new file mode 100644 index 0000000..6388025 --- /dev/null +++ b/res/layout/settings_actionbar.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java index 2ce0bcc..50aa1df 100644 --- a/src/com/android/settings/Settings.java +++ b/src/com/android/settings/Settings.java @@ -18,6 +18,7 @@ package com.android.settings; import android.app.Activity; import android.app.Fragment; +import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.preference.Preference; @@ -25,8 +26,13 @@ import android.preference.PreferenceFragment; import android.preference.PreferenceGroup; import android.preference.PreferenceScreen; import android.text.TextUtils; +import android.util.AttributeSet; import android.util.Log; +import android.view.LayoutInflater; import android.view.View; +import android.view.View.OnClickListener; +import android.widget.LinearLayout; +import android.widget.TextView; import java.util.ArrayList; @@ -37,6 +43,8 @@ public class Settings extends Activity implements PreferenceFragment.OnPreferenceStartFragmentCallback, SettingsPreferenceFragment.OnStateListener { + private static final boolean DBG = false; + private static final String TAG = "Settings"; private static final String KEY_PARENT = "parent"; @@ -52,22 +60,13 @@ public class Settings extends Activity public static final String EXTRA_SHOW_FRAGMENT_ARGUMENTS = ":settings:show_fragment_args"; - // Temporary, until all top-level settings are converted to fragments private static final String BACK_STACK_PREFS = ":settings:prefs"; private View mPrefsPane; private View mMainPane; private boolean mSinglePane; - private ArrayList mTrail = new ArrayList(); - - /* - @Override - protected void onResume() { - super.onResume(); - findPreference(KEY_CALL_SETTINGS).setEnabled(!AirplaneModeEnabler.isAirplaneModeOn(this)); - } - */ + private BreadCrumbs mBreadCrumbs; @Override protected void onCreate(Bundle savedInstanceState) { @@ -82,6 +81,8 @@ public class Settings extends Activity String initialFragment = intent.getStringExtra(EXTRA_SHOW_FRAGMENT); Bundle initialArguments = intent.getBundleExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS); + createActionBar(); + if (mSinglePane) { if (initialFragment != null) { showFragment(initialFragment, initialArguments); @@ -111,11 +112,21 @@ public class Settings extends Activity } } + private void createActionBar() { + LayoutInflater inflater = (LayoutInflater) + getSystemService(Context.LAYOUT_INFLATER_SERVICE); + View customNavBar = inflater.inflate(R.layout.settings_actionbar, null, false); + getActionBar().setCustomNavigationMode(customNavBar); + mBreadCrumbs = (BreadCrumbs) customNavBar.findViewById(R.id.bread_crumbs); + mBreadCrumbs.setActivity(this); + } + boolean showFragment(Preference preference) { if (mSinglePane) { startWithFragment(preference.getFragment(), preference.getExtras()); return false; } else { + mBreadCrumbs.clear(); return showFragment(preference.getFragment(), preference.getExtras()); } } @@ -129,10 +140,13 @@ public class Settings extends Activity } private boolean showFragment(String fragmentClass, Bundle extras) { - Fragment f = Fragment.instantiate(this, fragmentClass, extras); + if (DBG) Log.d(TAG, "showFragment"); + Fragment f = Fragment.instantiate(this, fragmentClass, extras); if (f instanceof SettingsPreferenceFragment) { ((SettingsPreferenceFragment) f).setOnStateListener(this); } + mBreadCrumbs.clear(); + getFragmentManager().popBackStack(BACK_STACK_PREFS, POP_BACK_STACK_INCLUSIVE); getFragmentManager().openTransaction().replace(R.id.prefs, f).commit(); return true; } @@ -140,41 +154,28 @@ public class Settings extends Activity private void addToBreadCrumbs(Fragment fragment) { final CharSequence title = ((PreferenceFragment) fragment) .getPreferenceScreen().getTitle(); - if (mSinglePane) mTrail.clear(); - if (mTrail.size() == 0 || !TextUtils.equals(title, mTrail.get(mTrail.size() - 1))) { - mTrail.add(title); - updateTitle(); + if (mSinglePane) { + mBreadCrumbs.clear(); } + mBreadCrumbs.push(title); } private void removeFromBreadCrumbs(Fragment fragment) { - if (mTrail.size() > 0) { - mTrail.remove(mTrail.size() - 1); - } - updateTitle(); - } - - private void updateTitle() { - String trail = ""; - for (CharSequence trailPart : mTrail) { - if (trail.length() != 0) - trail += " | "; - trail = trail + trailPart; - } - setTitle(trail); + mBreadCrumbs.pop(((PreferenceFragment) fragment).getPreferenceScreen().getTitle()); + mBreadCrumbs.update(); } public void onCreated(SettingsPreferenceFragment fragment) { - Log.d(TAG, "Fragment created " + fragment + " (name: " + fragment.getClass() + ")"); + if (DBG) Log.d(TAG, "Fragment created " + fragment); addToBreadCrumbs(fragment); } public void onDestroyed(SettingsPreferenceFragment fragment) { - removeFromBreadCrumbs(fragment); Log.d(TAG, "Fragment destroyed " + fragment + " (name: " + fragment.getClass() + ")"); } public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) { + if (DBG) Log.d(TAG, "onPreferenceStartFragment"); Fragment f = Fragment.instantiate(this, pref.getFragment(), pref.getExtras()); if (f instanceof SettingsPreferenceFragment) { ((SettingsPreferenceFragment) f).setOnStateListener(this); @@ -184,6 +185,13 @@ public class Settings extends Activity return true; } + @Override + public void onBackPressed() { + mBreadCrumbs.pop(); + mBreadCrumbs.update(); + super.onBackPressed(); + } + public static class TopLevelSettings extends PreferenceFragment { private IconPreferenceScreen mHighlightedPreference; @@ -198,6 +206,21 @@ public class Settings extends Activity updatePreferenceList(); } + @Override + public void onResume() { + super.onResume(); + + updateCallSettings(); + } + + private void updateCallSettings() { + Preference callSettings = findPreference(KEY_CALL_SETTINGS); + // Might have been removed in non-voice-capable devices + if (callSettings != null) { + callSettings.setEnabled(!AirplaneModeEnabler.isAirplaneModeOn(getActivity())); + } + } + private void updatePreferenceList() { final Activity activity = getActivity(); PreferenceGroup parent = (PreferenceGroup) findPreference(KEY_PARENT); @@ -247,4 +270,91 @@ public class Settings extends Activity onPreferenceTreeClick(getPreferenceScreen(), first); } } + + public static class BreadCrumbs extends LinearLayout implements OnClickListener { + + private ArrayList mTitles = new ArrayList(); + private TextView mLevelUpTitle; + private TextView mCurrentLevelTitle; + private View mDivider; + private Activity mActivity; + + public BreadCrumbs(Context context) { + this(context, null); + } + + public BreadCrumbs(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public void push(CharSequence title) { + if (mTitles.size() == 0 + || !TextUtils.equals(title, mTitles.get(mTitles.size() - 1))) { + mTitles.add(title); + update(); + } + } + + public void pop() { + if (mTitles.size() > 0) { + mTitles.remove(mTitles.size() - 1); + } + } + + public void pop(CharSequence title) { + if (mTitles.size() > 1) { + mTitles.remove(title); + } + } + + public void clear() { + mTitles.clear(); + } + + private void initNavViews() { + if (mLevelUpTitle == null) { + mLevelUpTitle = (TextView) findViewById(R.id.level_up_title); + mCurrentLevelTitle = (TextView) findViewById(R.id.level_current_title); + mDivider = findViewById(R.id.level_divider); + if (mLevelUpTitle != null) { + mLevelUpTitle.setOnClickListener(this); + } + if (mCurrentLevelTitle != null) { + mCurrentLevelTitle.setOnClickListener(this); + } + } + } + + public void update() { + initNavViews(); + if (mLevelUpTitle == null) return; + + final int titleCount = mTitles.size(); + if (titleCount > 1) { + mLevelUpTitle.setText(mTitles.get(titleCount - 2)); + mLevelUpTitle.setVisibility(VISIBLE); + mDivider.setVisibility(VISIBLE); + } else { + mLevelUpTitle.setVisibility(GONE); + mDivider.setVisibility(GONE); + } + if (titleCount > 0) { + mCurrentLevelTitle.setText(mTitles.get(titleCount - 1)); + } else { + mCurrentLevelTitle.setText(""); + } + } + + public void setActivity(Activity activity) { + mActivity = activity; + } + + public void onClick(View v) { + if (mActivity == null) + return; + if (v == mLevelUpTitle) { + mActivity.onBackPressed(); + } + } + } } diff --git a/src/com/android/settings/SettingsPreferenceFragment.java b/src/com/android/settings/SettingsPreferenceFragment.java index d10fda3..bddfb2b 100644 --- a/src/com/android/settings/SettingsPreferenceFragment.java +++ b/src/com/android/settings/SettingsPreferenceFragment.java @@ -51,6 +51,8 @@ public class SettingsPreferenceFragment extends PreferenceFragment { private Button mNextButton; + private boolean mReportedCreation; + interface OnStateListener { void onCreated(SettingsPreferenceFragment fragment); @@ -65,8 +67,10 @@ public class SettingsPreferenceFragment extends PreferenceFragment { @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - if (mOnStateListener != null) { + if (mOnStateListener != null && !mReportedCreation) { mOnStateListener.onCreated(this); + // So that we don't report it on the way back to this fragment + mReportedCreation = true; } setupButtonBar(); -- cgit v1.1