Breadcrumbs in the action bar for navigating up one level and showing current title.
Change-Id: I595e06549b888bd67c6dddd599a4cc77416c3a41
This commit is contained in:
@@ -49,7 +49,7 @@
|
|||||||
|
|
||||||
<activity android:name="Settings" android:label="@string/settings_label"
|
<activity android:name="Settings" android:label="@string/settings_label"
|
||||||
android:taskAffinity="com.android.settings"
|
android:taskAffinity="com.android.settings"
|
||||||
android:theme="@android:style/Theme.WithActionBar">
|
android:theme="@android:style/Theme.Holo">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<action android:name="android.settings.SETTINGS" />
|
<action android:name="android.settings.SETTINGS" />
|
||||||
|
BIN
res/drawable-hdpi/nav_divider.png
Normal file
BIN
res/drawable-hdpi/nav_divider.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1012 B |
BIN
res/drawable-mdpi/nav_divider.png
Normal file
BIN
res/drawable-mdpi/nav_divider.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
64
res/layout/settings_actionbar.xml
Normal file
64
res/layout/settings_actionbar.xml
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2010 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:padding="4dip"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<!-- ImageView
|
||||||
|
android:src="@drawable/ic_launcher_settings"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginLeft="4dip"
|
||||||
|
android:layout_marginRight="4dip"
|
||||||
|
/-->
|
||||||
|
|
||||||
|
<view class="com.android.settings.Settings$BreadCrumbs"
|
||||||
|
android:id="@+id/bread_crumbs"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView android:id="@+id/level_up_title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
style="?android:attr/textAppearanceMediumInverse"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/level_divider"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginTop="4dip"
|
||||||
|
android:layout_marginBottom="4dip"
|
||||||
|
android:layout_marginLeft="12dip"
|
||||||
|
android:layout_marginRight="12dip"
|
||||||
|
android:src="@drawable/nav_divider"/>
|
||||||
|
|
||||||
|
<TextView android:id="@+id/level_current_title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
style="?android:attr/textAppearanceMediumInverse"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</LinearLayout>
|
@@ -18,6 +18,7 @@ package com.android.settings;
|
|||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.Fragment;
|
import android.app.Fragment;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.preference.Preference;
|
import android.preference.Preference;
|
||||||
@@ -25,8 +26,13 @@ import android.preference.PreferenceFragment;
|
|||||||
import android.preference.PreferenceGroup;
|
import android.preference.PreferenceGroup;
|
||||||
import android.preference.PreferenceScreen;
|
import android.preference.PreferenceScreen;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
import android.util.AttributeSet;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.View.OnClickListener;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
@@ -37,6 +43,8 @@ public class Settings extends Activity
|
|||||||
implements PreferenceFragment.OnPreferenceStartFragmentCallback,
|
implements PreferenceFragment.OnPreferenceStartFragmentCallback,
|
||||||
SettingsPreferenceFragment.OnStateListener {
|
SettingsPreferenceFragment.OnStateListener {
|
||||||
|
|
||||||
|
private static final boolean DBG = false;
|
||||||
|
|
||||||
private static final String TAG = "Settings";
|
private static final String TAG = "Settings";
|
||||||
|
|
||||||
private static final String KEY_PARENT = "parent";
|
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";
|
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 static final String BACK_STACK_PREFS = ":settings:prefs";
|
||||||
|
|
||||||
private View mPrefsPane;
|
private View mPrefsPane;
|
||||||
private View mMainPane;
|
private View mMainPane;
|
||||||
private boolean mSinglePane;
|
private boolean mSinglePane;
|
||||||
|
|
||||||
private ArrayList<CharSequence> mTrail = new ArrayList<CharSequence>();
|
private BreadCrumbs mBreadCrumbs;
|
||||||
|
|
||||||
/*
|
|
||||||
@Override
|
|
||||||
protected void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
findPreference(KEY_CALL_SETTINGS).setEnabled(!AirplaneModeEnabler.isAirplaneModeOn(this));
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@@ -82,6 +81,8 @@ public class Settings extends Activity
|
|||||||
String initialFragment = intent.getStringExtra(EXTRA_SHOW_FRAGMENT);
|
String initialFragment = intent.getStringExtra(EXTRA_SHOW_FRAGMENT);
|
||||||
Bundle initialArguments = intent.getBundleExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS);
|
Bundle initialArguments = intent.getBundleExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS);
|
||||||
|
|
||||||
|
createActionBar();
|
||||||
|
|
||||||
if (mSinglePane) {
|
if (mSinglePane) {
|
||||||
if (initialFragment != null) {
|
if (initialFragment != null) {
|
||||||
showFragment(initialFragment, initialArguments);
|
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) {
|
boolean showFragment(Preference preference) {
|
||||||
if (mSinglePane) {
|
if (mSinglePane) {
|
||||||
startWithFragment(preference.getFragment(), preference.getExtras());
|
startWithFragment(preference.getFragment(), preference.getExtras());
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
mBreadCrumbs.clear();
|
||||||
return showFragment(preference.getFragment(), preference.getExtras());
|
return showFragment(preference.getFragment(), preference.getExtras());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -129,10 +140,13 @@ public class Settings extends Activity
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean showFragment(String fragmentClass, Bundle extras) {
|
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) {
|
if (f instanceof SettingsPreferenceFragment) {
|
||||||
((SettingsPreferenceFragment) f).setOnStateListener(this);
|
((SettingsPreferenceFragment) f).setOnStateListener(this);
|
||||||
}
|
}
|
||||||
|
mBreadCrumbs.clear();
|
||||||
|
getFragmentManager().popBackStack(BACK_STACK_PREFS, POP_BACK_STACK_INCLUSIVE);
|
||||||
getFragmentManager().openTransaction().replace(R.id.prefs, f).commit();
|
getFragmentManager().openTransaction().replace(R.id.prefs, f).commit();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -140,41 +154,28 @@ public class Settings extends Activity
|
|||||||
private void addToBreadCrumbs(Fragment fragment) {
|
private void addToBreadCrumbs(Fragment fragment) {
|
||||||
final CharSequence title = ((PreferenceFragment) fragment)
|
final CharSequence title = ((PreferenceFragment) fragment)
|
||||||
.getPreferenceScreen().getTitle();
|
.getPreferenceScreen().getTitle();
|
||||||
if (mSinglePane) mTrail.clear();
|
if (mSinglePane) {
|
||||||
if (mTrail.size() == 0 || !TextUtils.equals(title, mTrail.get(mTrail.size() - 1))) {
|
mBreadCrumbs.clear();
|
||||||
mTrail.add(title);
|
|
||||||
updateTitle();
|
|
||||||
}
|
}
|
||||||
|
mBreadCrumbs.push(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeFromBreadCrumbs(Fragment fragment) {
|
private void removeFromBreadCrumbs(Fragment fragment) {
|
||||||
if (mTrail.size() > 0) {
|
mBreadCrumbs.pop(((PreferenceFragment) fragment).getPreferenceScreen().getTitle());
|
||||||
mTrail.remove(mTrail.size() - 1);
|
mBreadCrumbs.update();
|
||||||
}
|
|
||||||
updateTitle();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateTitle() {
|
|
||||||
String trail = "";
|
|
||||||
for (CharSequence trailPart : mTrail) {
|
|
||||||
if (trail.length() != 0)
|
|
||||||
trail += " | ";
|
|
||||||
trail = trail + trailPart;
|
|
||||||
}
|
|
||||||
setTitle(trail);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onCreated(SettingsPreferenceFragment fragment) {
|
public void onCreated(SettingsPreferenceFragment fragment) {
|
||||||
Log.d(TAG, "Fragment created " + fragment + " (name: " + fragment.getClass() + ")");
|
if (DBG) Log.d(TAG, "Fragment created " + fragment);
|
||||||
addToBreadCrumbs(fragment);
|
addToBreadCrumbs(fragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onDestroyed(SettingsPreferenceFragment fragment) {
|
public void onDestroyed(SettingsPreferenceFragment fragment) {
|
||||||
removeFromBreadCrumbs(fragment);
|
|
||||||
Log.d(TAG, "Fragment destroyed " + fragment + " (name: " + fragment.getClass() + ")");
|
Log.d(TAG, "Fragment destroyed " + fragment + " (name: " + fragment.getClass() + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) {
|
public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) {
|
||||||
|
if (DBG) Log.d(TAG, "onPreferenceStartFragment");
|
||||||
Fragment f = Fragment.instantiate(this, pref.getFragment(), pref.getExtras());
|
Fragment f = Fragment.instantiate(this, pref.getFragment(), pref.getExtras());
|
||||||
if (f instanceof SettingsPreferenceFragment) {
|
if (f instanceof SettingsPreferenceFragment) {
|
||||||
((SettingsPreferenceFragment) f).setOnStateListener(this);
|
((SettingsPreferenceFragment) f).setOnStateListener(this);
|
||||||
@@ -184,6 +185,13 @@ public class Settings extends Activity
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
mBreadCrumbs.pop();
|
||||||
|
mBreadCrumbs.update();
|
||||||
|
super.onBackPressed();
|
||||||
|
}
|
||||||
|
|
||||||
public static class TopLevelSettings extends PreferenceFragment {
|
public static class TopLevelSettings extends PreferenceFragment {
|
||||||
|
|
||||||
private IconPreferenceScreen mHighlightedPreference;
|
private IconPreferenceScreen mHighlightedPreference;
|
||||||
@@ -198,6 +206,21 @@ public class Settings extends Activity
|
|||||||
updatePreferenceList();
|
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() {
|
private void updatePreferenceList() {
|
||||||
final Activity activity = getActivity();
|
final Activity activity = getActivity();
|
||||||
PreferenceGroup parent = (PreferenceGroup) findPreference(KEY_PARENT);
|
PreferenceGroup parent = (PreferenceGroup) findPreference(KEY_PARENT);
|
||||||
@@ -247,4 +270,91 @@ public class Settings extends Activity
|
|||||||
onPreferenceTreeClick(getPreferenceScreen(), first);
|
onPreferenceTreeClick(getPreferenceScreen(), first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class BreadCrumbs extends LinearLayout implements OnClickListener {
|
||||||
|
|
||||||
|
private ArrayList<CharSequence> mTitles = new ArrayList<CharSequence>();
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -51,6 +51,8 @@ public class SettingsPreferenceFragment extends PreferenceFragment {
|
|||||||
|
|
||||||
private Button mNextButton;
|
private Button mNextButton;
|
||||||
|
|
||||||
|
private boolean mReportedCreation;
|
||||||
|
|
||||||
interface OnStateListener {
|
interface OnStateListener {
|
||||||
|
|
||||||
void onCreated(SettingsPreferenceFragment fragment);
|
void onCreated(SettingsPreferenceFragment fragment);
|
||||||
@@ -65,8 +67,10 @@ public class SettingsPreferenceFragment extends PreferenceFragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onActivityCreated(Bundle savedInstanceState) {
|
public void onActivityCreated(Bundle savedInstanceState) {
|
||||||
super.onActivityCreated(savedInstanceState);
|
super.onActivityCreated(savedInstanceState);
|
||||||
if (mOnStateListener != null) {
|
if (mOnStateListener != null && !mReportedCreation) {
|
||||||
mOnStateListener.onCreated(this);
|
mOnStateListener.onCreated(this);
|
||||||
|
// So that we don't report it on the way back to this fragment
|
||||||
|
mReportedCreation = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
setupButtonBar();
|
setupButtonBar();
|
||||||
|
Reference in New Issue
Block a user