Merge "Fix Fragment BackStack and Titles"
This commit is contained in:
committed by
Android (Google) Code Review
commit
947d8143b9
@@ -62,10 +62,8 @@ import android.support.v4.widget.DrawerLayout;
|
|||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Pair;
|
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
import android.util.Xml;
|
import android.util.Xml;
|
||||||
import android.view.ContextThemeWrapper;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@@ -200,6 +198,8 @@ public class SettingsActivity extends Activity
|
|||||||
private Header mSelectedHeader;
|
private Header mSelectedHeader;
|
||||||
private Header mCurrentHeader;
|
private Header mCurrentHeader;
|
||||||
|
|
||||||
|
private CharSequence mInitialTitle;
|
||||||
|
|
||||||
// Show only these settings for restricted users
|
// Show only these settings for restricted users
|
||||||
private int[] SETTINGS_FOR_RESTRICTED = {
|
private int[] SETTINGS_FOR_RESTRICTED = {
|
||||||
R.id.wireless_section,
|
R.id.wireless_section,
|
||||||
@@ -314,39 +314,6 @@ public class SettingsActivity extends Activity
|
|||||||
private final ArrayList<Header> mHeaders = new ArrayList<Header>();
|
private final ArrayList<Header> mHeaders = new ArrayList<Header>();
|
||||||
private HeaderAdapter mHeaderAdapter;
|
private HeaderAdapter mHeaderAdapter;
|
||||||
|
|
||||||
static private class TitlePair extends Pair<Integer, CharSequence> implements Parcelable {
|
|
||||||
|
|
||||||
public TitlePair(Integer first, CharSequence second) {
|
|
||||||
super(first, second);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int describeContents() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeToParcel(Parcel dest, int flags) {
|
|
||||||
dest.writeInt(first);
|
|
||||||
TextUtils.writeToParcel(second, dest, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
TitlePair(Parcel in) {
|
|
||||||
super(in.readInt(), TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final Creator<TitlePair> CREATOR = new Creator<TitlePair>() {
|
|
||||||
public TitlePair createFromParcel(Parcel source) {
|
|
||||||
return new TitlePair(source);
|
|
||||||
}
|
|
||||||
public TitlePair[] newArray(int size) {
|
|
||||||
return new TitlePair[size];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private final ArrayList<TitlePair> mTitleStack = new ArrayList<TitlePair>();
|
|
||||||
|
|
||||||
private DrawerLayout mDrawerLayout;
|
private DrawerLayout mDrawerLayout;
|
||||||
private ListView mDrawer;
|
private ListView mDrawer;
|
||||||
private ActionBarDrawerToggle mDrawerToggle;
|
private ActionBarDrawerToggle mDrawerToggle;
|
||||||
@@ -409,7 +376,7 @@ public class SettingsActivity extends Activity
|
|||||||
if (isFinishing() || mSelectedHeader == null) {
|
if (isFinishing() || mSelectedHeader == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switchToHeader(mSelectedHeader, false);
|
switchToHeader(mSelectedHeader, false, false);
|
||||||
mSelectedHeader = null;
|
mSelectedHeader = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -557,17 +524,8 @@ public class SettingsActivity extends Activity
|
|||||||
if (savedInstanceState != null) {
|
if (savedInstanceState != null) {
|
||||||
// We are restarting from a previous saved state; used that to
|
// We are restarting from a previous saved state; used that to
|
||||||
// initialize, instead of starting fresh.
|
// initialize, instead of starting fresh.
|
||||||
|
mInitialTitle = getTitle();
|
||||||
ArrayList<TitlePair> titles =
|
setTitleFromBackStack();
|
||||||
savedInstanceState.getParcelableArrayList(SAVE_KEY_TITLES_TAG);
|
|
||||||
if (titles != null) {
|
|
||||||
mTitleStack.addAll(titles);
|
|
||||||
}
|
|
||||||
final int lastTitle = mTitleStack.size() - 1;
|
|
||||||
if (lastTitle >= 0) {
|
|
||||||
final TitlePair last = mTitleStack.get(lastTitle);
|
|
||||||
setTitleFromPair(last);
|
|
||||||
}
|
|
||||||
|
|
||||||
ArrayList<Header> headers =
|
ArrayList<Header> headers =
|
||||||
savedInstanceState.getParcelableArrayList(SAVE_KEY_HEADERS_TAG);
|
savedInstanceState.getParcelableArrayList(SAVE_KEY_HEADERS_TAG);
|
||||||
@@ -579,18 +537,15 @@ public class SettingsActivity extends Activity
|
|||||||
setSelectedHeader(mHeaders.get(curHeader));
|
setSelectedHeader(mHeaders.get(curHeader));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (initialFragment != null) {
|
if (initialFragment != null) {
|
||||||
// If we are just showing a fragment, we want to run in
|
// If we are just showing a fragment, we want to run in
|
||||||
// new fragment mode, but don't need to compute and show
|
// new fragment mode, but don't need to compute and show
|
||||||
// the headers.
|
// the headers.
|
||||||
switchToHeader(initialFragment, initialArguments, true);
|
final int initialTitleResId = getIntent().getIntExtra(EXTRA_SHOW_FRAGMENT_TITLE, 0);
|
||||||
|
mInitialTitle = (initialTitleResId > 0) ? getText(initialTitleResId) : getTitle();
|
||||||
|
|
||||||
final int initialTitle = getIntent().getIntExtra(EXTRA_SHOW_FRAGMENT_TITLE, 0);
|
switchToHeader(initialFragment, initialArguments, true, mInitialTitle);
|
||||||
if (initialTitle != 0) {
|
|
||||||
setTitle(getText(initialTitle));
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// We need to try to build the headers.
|
// We need to try to build the headers.
|
||||||
onBuildHeaders(mHeaders);
|
onBuildHeaders(mHeaders);
|
||||||
@@ -600,7 +555,8 @@ public class SettingsActivity extends Activity
|
|||||||
// the currently selected preference fragment.
|
// the currently selected preference fragment.
|
||||||
if (mHeaders.size() > 0) {
|
if (mHeaders.size() > 0) {
|
||||||
Header h = onGetInitialHeader();
|
Header h = onGetInitialHeader();
|
||||||
switchToHeader(h, false);
|
mInitialTitle = getHeaderTitle(h);
|
||||||
|
switchToHeader(h, false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -667,32 +623,30 @@ public class SettingsActivity extends Activity
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBackStackChanged() {
|
public void onBackStackChanged() {
|
||||||
final int count = getFragmentManager().getBackStackEntryCount() + 1;
|
setTitleFromBackStack();
|
||||||
TitlePair pair = null;
|
|
||||||
int last;
|
|
||||||
while (mTitleStack.size() > count) {
|
|
||||||
last = mTitleStack.size() - 1;
|
|
||||||
pair = mTitleStack.remove(last);
|
|
||||||
}
|
|
||||||
// Check if we go back
|
|
||||||
if (pair != null) {
|
|
||||||
int size = mTitleStack.size();
|
|
||||||
if (size > 0) {
|
|
||||||
last = mTitleStack.size() - 1;
|
|
||||||
pair = mTitleStack.get(last);
|
|
||||||
setTitleFromPair(pair);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setTitleFromPair(TitlePair pair) {
|
private void setTitleFromBackStack() {
|
||||||
final CharSequence title;
|
final int count = getFragmentManager().getBackStackEntryCount();
|
||||||
if (pair.first > 0) {
|
if (count == 0) {
|
||||||
title = getText(pair.first);
|
setTitle(mInitialTitle);
|
||||||
} else {
|
return;
|
||||||
title = pair.second;
|
}
|
||||||
|
FragmentManager.BackStackEntry bse = getFragmentManager().getBackStackEntryAt(count - 1);
|
||||||
|
setTitleFromBackStackEntry(bse);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setTitleFromBackStackEntry(FragmentManager.BackStackEntry bse) {
|
||||||
|
final CharSequence title;
|
||||||
|
final int titleRes = bse.getBreadCrumbTitleRes();
|
||||||
|
if (titleRes > 0) {
|
||||||
|
title = getText(titleRes);
|
||||||
|
} else {
|
||||||
|
title = bse.getBreadCrumbTitle();
|
||||||
|
}
|
||||||
|
if (title != null) {
|
||||||
|
setTitle(title);
|
||||||
}
|
}
|
||||||
setTitle(title);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -715,10 +669,6 @@ public class SettingsActivity extends Activity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mTitleStack.size() > 0) {
|
|
||||||
outState.putParcelableList(SAVE_KEY_TITLES_TAG, mTitleStack);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -783,9 +733,10 @@ public class SettingsActivity extends Activity
|
|||||||
* preference fragment.
|
* preference fragment.
|
||||||
*
|
*
|
||||||
* @param header The new header to display.
|
* @param header The new header to display.
|
||||||
* @param validate true means that the fragment's Header needs to be validated
|
* @param validate true means that the fragment's Header needs to be validated.
|
||||||
|
* @param initial true means that it is the initial Header.
|
||||||
*/
|
*/
|
||||||
private void switchToHeader(Header header, boolean validate) {
|
private void switchToHeader(Header header, boolean validate, boolean initial) {
|
||||||
if (header == null) {
|
if (header == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -799,15 +750,11 @@ public class SettingsActivity extends Activity
|
|||||||
FragmentManager.POP_BACK_STACK_INCLUSIVE);
|
FragmentManager.POP_BACK_STACK_INCLUSIVE);
|
||||||
} else {
|
} else {
|
||||||
if (header.fragment != null) {
|
if (header.fragment != null) {
|
||||||
mTitleStack.clear();
|
switchToHeaderInner(header.fragment, header.fragmentArguments, validate, !initial,
|
||||||
switchToHeaderInner(header.fragment, header.fragmentArguments, validate);
|
getHeaderTitle(header));
|
||||||
setSelectedHeader(header);
|
setSelectedHeader(header);
|
||||||
final TitlePair pair = new TitlePair(0, getHeaderTitle(header));
|
|
||||||
mTitleStack.add(pair);
|
|
||||||
setTitle(pair.second);
|
|
||||||
} else if (header.intent != null) {
|
} else if (header.intent != null) {
|
||||||
setSelectedHeader(header);
|
setSelectedHeader(header);
|
||||||
mTitleStack.clear();
|
|
||||||
startActivity(header.intent);
|
startActivity(header.intent);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
@@ -861,19 +808,20 @@ public class SettingsActivity extends Activity
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When in two-pane mode, switch the fragment pane to show the given
|
* Switch the fragment pane to show the given preference fragment.
|
||||||
* preference fragment.
|
|
||||||
*
|
*
|
||||||
* @param fragmentName The name of the fragment to display.
|
* @param fragmentName The name of the fragment to display.
|
||||||
* @param args Optional arguments to supply to the fragment.
|
* @param args Optional arguments to supply to the fragment.
|
||||||
* @param validate true means that the fragment's Header needs to be validated
|
* @param validate true means that the fragment's Header needs to be validated
|
||||||
*/
|
*/
|
||||||
private void switchToHeader(String fragmentName, Bundle args, boolean validate) {
|
private void switchToHeader(String fragmentName, Bundle args, boolean validate,
|
||||||
|
CharSequence title) {
|
||||||
setSelectedHeader(null);
|
setSelectedHeader(null);
|
||||||
switchToHeaderInner(fragmentName, args, validate);
|
switchToHeaderInner(fragmentName, args, validate, false, title);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void switchToHeaderInner(String fragmentName, Bundle args, boolean validate) {
|
private void switchToHeaderInner(String fragmentName, Bundle args, boolean validate,
|
||||||
|
boolean addToBackStack, CharSequence title) {
|
||||||
getFragmentManager().popBackStack(BACK_STACK_PREFS,
|
getFragmentManager().popBackStack(BACK_STACK_PREFS,
|
||||||
FragmentManager.POP_BACK_STACK_INCLUSIVE);
|
FragmentManager.POP_BACK_STACK_INCLUSIVE);
|
||||||
if (validate && !isValidFragment(fragmentName)) {
|
if (validate && !isValidFragment(fragmentName)) {
|
||||||
@@ -882,8 +830,14 @@ public class SettingsActivity extends Activity
|
|||||||
}
|
}
|
||||||
Fragment f = Fragment.instantiate(this, fragmentName, args);
|
Fragment f = Fragment.instantiate(this, fragmentName, args);
|
||||||
FragmentTransaction transaction = getFragmentManager().beginTransaction();
|
FragmentTransaction transaction = getFragmentManager().beginTransaction();
|
||||||
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
|
|
||||||
transaction.replace(R.id.prefs, f);
|
transaction.replace(R.id.prefs, f);
|
||||||
|
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
|
||||||
|
if (addToBackStack) {
|
||||||
|
transaction.addToBackStack(BACK_STACK_PREFS);
|
||||||
|
}
|
||||||
|
if (title != null) {
|
||||||
|
transaction.setBreadCrumbTitle(title);
|
||||||
|
}
|
||||||
transaction.commitAllowingStateLoss();
|
transaction.commitAllowingStateLoss();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1037,6 +991,13 @@ public class SettingsActivity extends Activity
|
|||||||
*/
|
*/
|
||||||
private void startWithFragment(String fragmentName, Bundle args, Fragment resultTo,
|
private void startWithFragment(String fragmentName, Bundle args, Fragment resultTo,
|
||||||
int resultRequestCode, int titleRes, CharSequence titleText) {
|
int resultRequestCode, int titleRes, CharSequence titleText) {
|
||||||
|
final CharSequence cs;
|
||||||
|
if (titleRes != 0) {
|
||||||
|
cs = getText(titleRes);
|
||||||
|
} else {
|
||||||
|
cs = titleText;
|
||||||
|
}
|
||||||
|
|
||||||
Fragment f = Fragment.instantiate(this, fragmentName, args);
|
Fragment f = Fragment.instantiate(this, fragmentName, args);
|
||||||
if (resultTo != null) {
|
if (resultTo != null) {
|
||||||
f.setTargetFragment(resultTo, resultRequestCode);
|
f.setTargetFragment(resultTo, resultRequestCode);
|
||||||
@@ -1045,19 +1006,8 @@ public class SettingsActivity extends Activity
|
|||||||
transaction.replace(R.id.prefs, f);
|
transaction.replace(R.id.prefs, f);
|
||||||
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
|
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
|
||||||
transaction.addToBackStack(BACK_STACK_PREFS);
|
transaction.addToBackStack(BACK_STACK_PREFS);
|
||||||
|
transaction.setBreadCrumbTitle(cs);
|
||||||
transaction.commitAllowingStateLoss();
|
transaction.commitAllowingStateLoss();
|
||||||
|
|
||||||
final TitlePair pair;
|
|
||||||
final CharSequence cs;
|
|
||||||
if (titleRes != 0) {
|
|
||||||
pair = new TitlePair(titleRes, null);
|
|
||||||
cs = getText(titleRes);
|
|
||||||
} else {
|
|
||||||
pair = new TitlePair(0, titleText);
|
|
||||||
cs = titleText;
|
|
||||||
}
|
|
||||||
setTitle(cs);
|
|
||||||
mTitleStack.add(pair);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user