Remove card stack
Obsoletes a bunch of convoluted and probably brittle fragment management
code.
b/22179367
Change-Id: I3aa17c3d7e682c6a54710561bb877f3d7a8550df
diff --git a/v14/preference/src/android/support/v14/preference/PreferenceFragment.java b/v14/preference/src/android/support/v14/preference/PreferenceFragment.java
index a51dab3..e8cb6b6 100644
--- a/v14/preference/src/android/support/v14/preference/PreferenceFragment.java
+++ b/v14/preference/src/android/support/v14/preference/PreferenceFragment.java
@@ -406,8 +406,8 @@
public boolean onPreferenceTreeClick(Preference preference) {
if (preference.getFragment() != null) {
boolean handled = false;
- if (getTargetFragment() instanceof OnPreferenceStartFragmentCallback) {
- handled = ((OnPreferenceStartFragmentCallback) getTargetFragment())
+ if (getCallbackFragment() instanceof OnPreferenceStartFragmentCallback) {
+ handled = ((OnPreferenceStartFragmentCallback) getCallbackFragment())
.onPreferenceStartFragment(this, preference);
}
if (!handled && getActivity() instanceof OnPreferenceStartFragmentCallback){
@@ -432,8 +432,8 @@
@Override
public void onNavigateToScreen(PreferenceScreen preferenceScreen) {
boolean handled = false;
- if (getTargetFragment() instanceof OnPreferenceStartScreenCallback) {
- handled = ((OnPreferenceStartScreenCallback) getTargetFragment())
+ if (getCallbackFragment() instanceof OnPreferenceStartScreenCallback) {
+ handled = ((OnPreferenceStartScreenCallback) getCallbackFragment())
.onPreferenceStartScreen(this, preferenceScreen);
}
if (!handled && getActivity() instanceof OnPreferenceStartScreenCallback) {
@@ -541,8 +541,8 @@
public void onDisplayPreferenceDialog(Preference preference) {
boolean handled = false;
- if (getTargetFragment() instanceof OnPreferenceDisplayDialogCallback) {
- handled = ((OnPreferenceDisplayDialogCallback) getTargetFragment())
+ if (getCallbackFragment() instanceof OnPreferenceDisplayDialogCallback) {
+ handled = ((OnPreferenceDisplayDialogCallback) getCallbackFragment())
.onPreferenceDisplayDialog(this, preference);
}
if (!handled && getActivity() instanceof OnPreferenceDisplayDialogCallback) {
@@ -574,4 +574,12 @@
f.show(getFragmentManager(), DIALOG_FRAGMENT_TAG);
}
+ /**
+ * Basically a wrapper for getParentFragment which is v17+. Used by the leanback preference lib.
+ * @return Fragment to possibly use as a callback
+ * @hide
+ */
+ public Fragment getCallbackFragment() {
+ return null;
+ }
}
diff --git a/v17/preference-leanback/api/current.txt b/v17/preference-leanback/api/current.txt
index b31306c..675a18e 100644
--- a/v17/preference-leanback/api/current.txt
+++ b/v17/preference-leanback/api/current.txt
@@ -60,8 +60,8 @@
ctor public LeanbackSettingsFragment();
method public boolean onPreferenceDisplayDialog(android.support.v14.preference.PreferenceFragment, android.support.v7.preference.Preference);
method public abstract void onPreferenceStartInitialScreen();
- method public void startImmersiveFragment(android.app.Fragment, java.lang.String);
- method public void startPreferenceFragment(android.app.Fragment, java.lang.String);
+ method public void startImmersiveFragment(android.app.Fragment);
+ method public void startPreferenceFragment(android.app.Fragment);
}
}
diff --git a/v17/preference-leanback/res/layout/leanback_settings_fragment.xml b/v17/preference-leanback/res/layout/leanback_settings_fragment.xml
index 5cf3e51..e9c421e 100644
--- a/v17/preference-leanback/res/layout/leanback_settings_fragment.xml
+++ b/v17/preference-leanback/res/layout/leanback_settings_fragment.xml
@@ -15,6 +15,12 @@
~ limitations under the License
-->
<android.support.v17.preference.LeanbackSettingsRootView xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/settings_fragment_container"
+ android:id="@+id/settings_dialog_container"
android:layout_width="match_parent"
- android:layout_height="match_parent"/>
+ android:layout_height="match_parent">
+ <FrameLayout
+ android:id="@+id/settings_preference_fragment_container"
+ android:layout_width="@dimen/lb_settings_pane_width"
+ android:layout_height="match_parent"
+ android:layout_gravity="end"/>
+</android.support.v17.preference.LeanbackSettingsRootView>
diff --git a/v17/preference-leanback/res/layout/leanback_settings_fragment_stack.xml b/v17/preference-leanback/res/layout/leanback_settings_fragment_stack.xml
deleted file mode 100644
index 568c41e..0000000
--- a/v17/preference-leanback/res/layout/leanback_settings_fragment_stack.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2015 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
- -->
-<android.support.v17.leanback.view.StackedLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:id="@+id/settings_preference_stack"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- app:cardWidth="@dimen/lb_settings_card_width"
- app:stackShift="@dimen/lb_settings_card_shift"
- app:elevationIncrement="@dimen/lb_settings_card_elevation"
- />
diff --git a/v17/preference-leanback/res/values/dimens.xml b/v17/preference-leanback/res/values/dimens.xml
index c3e519f..49763fe 100644
--- a/v17/preference-leanback/res/values/dimens.xml
+++ b/v17/preference-leanback/res/values/dimens.xml
@@ -21,7 +21,5 @@
<dimen name="lb_preference_decor_title_padding_end">56dp</dimen>
<dimen name="lb_preference_decor_title_text_size">20sp</dimen>
- <dimen name="lb_settings_card_width">360dp</dimen>
- <dimen name="lb_settings_card_shift">72dp</dimen>
- <dimen name="lb_settings_card_elevation">12dp</dimen>
+ <dimen name="lb_settings_pane_width">360dp</dimen>
</resources>
diff --git a/v17/preference-leanback/src/android/support/v17/preference/BaseLeanbackPreferenceFragment.java b/v17/preference-leanback/src/android/support/v17/preference/BaseLeanbackPreferenceFragment.java
index 40d9607..6fc1fa6 100644
--- a/v17/preference-leanback/src/android/support/v17/preference/BaseLeanbackPreferenceFragment.java
+++ b/v17/preference-leanback/src/android/support/v17/preference/BaseLeanbackPreferenceFragment.java
@@ -16,6 +16,7 @@
package android.support.v17.preference;
+import android.app.Fragment;
import android.os.Bundle;
import android.support.v14.preference.PreferenceFragment;
import android.support.v17.leanback.widget.VerticalGridView;
@@ -38,4 +39,12 @@
verticalGridView.setFocusScrollStrategy(VerticalGridView.FOCUS_SCROLL_ALIGNED);
return verticalGridView;
}
+
+ /**
+ * @hide
+ */
+ @Override
+ public Fragment getCallbackFragment() {
+ return getParentFragment();
+ }
}
diff --git a/v17/preference-leanback/src/android/support/v17/preference/LeanbackSettingsFragment.java b/v17/preference-leanback/src/android/support/v17/preference/LeanbackSettingsFragment.java
index 38ef3d9..c6a7e94 100644
--- a/v17/preference-leanback/src/android/support/v17/preference/LeanbackSettingsFragment.java
+++ b/v17/preference-leanback/src/android/support/v17/preference/LeanbackSettingsFragment.java
@@ -20,12 +20,10 @@
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
import android.support.v14.preference.MultiSelectListPreference;
import android.support.v14.preference.PreferenceFragment;
import android.support.v7.preference.ListPreference;
import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceScreen;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
@@ -36,10 +34,8 @@
PreferenceFragment.OnPreferenceStartScreenCallback,
PreferenceFragment.OnPreferenceDisplayDialogCallback {
- private static final String SETTINGS_FRAGMENT_INNER_TAG =
- "android.support.v17.preference.LeanbackSettingsFragment.INNER_FRAGMENT";
-
- private boolean mInitialScreen;
+ private static final String PREFERENCE_FRAGMENT_TAG =
+ "android.support.v17.preference.LeanbackSettingsFragment.PREFERENCE_FRAGMENT";
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
@@ -56,14 +52,7 @@
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (savedInstanceState == null) {
- final Fragment f = new LeanbackSettingsFragmentInner();
- getChildFragmentManager().beginTransaction()
- .add(R.id.settings_fragment_container, f, SETTINGS_FRAGMENT_INNER_TAG)
- .commit();
- getChildFragmentManager().executePendingTransactions();
- mInitialScreen = true;
onPreferenceStartInitialScreen();
- mInitialScreen = false;
}
}
@@ -73,11 +62,11 @@
if (pref instanceof ListPreference) {
final ListPreference listPreference = (ListPreference) pref;
f = LeanbackListPreferenceDialogFragment.newInstanceSingle(listPreference.getKey());
- getInnerFragment().startDialogFragment(f, caller, null);
+ startImmersiveFragment(f);
} else if (pref instanceof MultiSelectListPreference) {
MultiSelectListPreference listPreference = (MultiSelectListPreference) pref;
f = LeanbackListPreferenceDialogFragment.newInstanceMulti(listPreference.getKey());
- getInnerFragment().startDialogFragment(f, caller, null);
+ startImmersiveFragment(f);
}
// TODO
// else if (pref instanceof EditTextPreference) {
@@ -92,7 +81,7 @@
/**
* Called to instantiate the initial {@link android.support.v14.preference.PreferenceFragment}
* to be shown in this fragment. Implementations are expected to call
- * {@link #startPreferenceFragment(android.app.Fragment, java.lang.String)}.
+ * {@link #startPreferenceFragment(android.app.Fragment)}.
*/
public abstract void onPreferenceStartInitialScreen();
@@ -101,171 +90,49 @@
* list-style fragments on top of the stack of preference fragments.
*
* @param fragment Fragment instance to be added.
- * @param tag Fragment tag
*/
- public void startPreferenceFragment(@NonNull Fragment fragment, @Nullable String tag) {
- getInnerFragment().startStackedFragment(fragment, tag, !mInitialScreen);
+ public void startPreferenceFragment(@NonNull Fragment fragment) {
+ fragment.setTargetFragment(this, 0);
+ final FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
+ final Fragment prevFragment =
+ getChildFragmentManager().findFragmentByTag(PREFERENCE_FRAGMENT_TAG);
+ if (prevFragment != null) {
+ transaction
+ .addToBackStack(null)
+ .replace(R.id.settings_preference_fragment_container, fragment,
+ PREFERENCE_FRAGMENT_TAG);
+ } else {
+ transaction
+ .add(R.id.settings_preference_fragment_container, fragment,
+ PREFERENCE_FRAGMENT_TAG);
+ }
+ transaction.commit();
}
/**
* Displays a fragment to the user, temporarily replacing the contents of this fragment.
*
* @param fragment Fragment instance to be added.
- * @param tag Fragment tag
*/
- public void startImmersiveFragment(@NonNull Fragment fragment, @Nullable String tag) {
- getChildFragmentManager().beginTransaction()
- .replace(R.id.settings_fragment_container, fragment, tag)
+ public void startImmersiveFragment(@NonNull Fragment fragment) {
+ final FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
+ final Fragment preferenceFragment =
+ getChildFragmentManager().findFragmentByTag(PREFERENCE_FRAGMENT_TAG);
+ if (preferenceFragment != null) {
+ transaction.hide(preferenceFragment);
+ }
+ transaction
+ .add(R.id.settings_dialog_container, fragment)
.addToBackStack(null)
.commit();
}
- private LeanbackSettingsFragmentInner getInnerFragment() {
- return (LeanbackSettingsFragmentInner)
- getChildFragmentManager().findFragmentByTag(SETTINGS_FRAGMENT_INNER_TAG);
- }
-
- private boolean handleBackPress() {
- final LeanbackSettingsFragmentInner inner = getInnerFragment();
- boolean handled = false;
- if (inner != null && inner.isVisible()) {
- handled = inner.handleBackPress();
- }
- return handled || getChildFragmentManager().popBackStackImmediate();
- }
-
- /**
- * @hide
- */
- public static class LeanbackSettingsFragmentInner extends Fragment
- implements LeanbackPreferenceDialogFragment.TargetFragment {
-
- private static final String SAVESTATE_TARGET_PREF_FRAG =
- "android.support.v17.preference.LeanbackSettingsFragment.TARGET_PREF_FRAG";
-
- private static final String TARGET_FRAGMENT_TAG =
- "android.support.v17.preference.LeanbackSettingsFragment.TARGET";
-
- // Preference fragment which last launched a dialog
- private PreferenceFragment mTargetPreferenceFragment;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- if (savedInstanceState != null &&
- savedInstanceState.containsKey(SAVESTATE_TARGET_PREF_FRAG)) {
- mTargetPreferenceFragment = (PreferenceFragment) getChildFragmentManager()
- .getFragment(savedInstanceState, SAVESTATE_TARGET_PREF_FRAG);
- }
- }
-
- @Override
- public @Nullable View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- return inflater.inflate(R.layout.leanback_settings_fragment_stack,
- container, false);
- }
-
- @Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- if (mTargetPreferenceFragment != null) {
- getChildFragmentManager().putFragment(outState, SAVESTATE_TARGET_PREF_FRAG,
- mTargetPreferenceFragment);
- }
- }
-
- public void startDialogFragment(@NonNull Fragment dialogFragment,
- @NonNull PreferenceFragment requestingFragment, @Nullable String tag) {
- mTargetPreferenceFragment = requestingFragment;
- startFragment(dialogFragment, tag, true);
- }
-
- public void startStackedFragment(@NonNull Fragment fragment, @Nullable String tag,
- boolean addToBackstack) {
- fragment.setTargetFragment(findTarget(), 0);
- startFragment(fragment, tag, addToBackstack);
- }
-
- private void startFragment(@NonNull Fragment fragment, @Nullable String tag,
- boolean addToBackstack) {
- final FragmentTransaction transaction = getChildFragmentManager().beginTransaction()
- .add(R.id.settings_preference_stack, fragment, tag);
- if (addToBackstack) {
- transaction.addToBackStack(null);
- }
- transaction.commit();
- }
-
- private Fragment findTarget() {
- Fragment target =
- getChildFragmentManager().findFragmentByTag(TARGET_FRAGMENT_TAG);
- if (target == null) {
- target = new Target();
- getChildFragmentManager().beginTransaction()
- .add(target, TARGET_FRAGMENT_TAG)
- .commit();
- getChildFragmentManager().executePendingTransactions();
- }
- return target;
- }
-
- public boolean handleBackPress() {
- return getChildFragmentManager().popBackStackImmediate();
- }
-
- public Preference findPreference(CharSequence key) {
- return mTargetPreferenceFragment.findPreference(key);
- }
-
- public PreferenceFragment getPreferenceFragment() {
- return mTargetPreferenceFragment;
- }
-
- @Override
- public LeanbackSettingsFragment getSettingsFragment() {
- return (LeanbackSettingsFragment) getParentFragment();
- }
-
- // This looks terrible, and it is. We need this because the target fragment needs to be
- // in the same FragmentManager as the fragment targeting it.
- /**
- * @hide
- */
- public static class Target extends Fragment
- implements PreferenceFragment.OnPreferenceStartFragmentCallback,
- PreferenceFragment.OnPreferenceStartScreenCallback,
- PreferenceFragment.OnPreferenceDisplayDialogCallback {
-
- private LeanbackSettingsFragment getOuterParent() {
- return (LeanbackSettingsFragment) getParentFragment().getParentFragment();
- }
-
- @Override
- public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) {
- return getOuterParent().onPreferenceStartFragment(caller, pref);
- }
-
- @Override
- public boolean onPreferenceStartScreen(PreferenceFragment caller,
- PreferenceScreen pref) {
- return getOuterParent().onPreferenceStartScreen(caller, pref);
- }
-
- @Override
- public boolean onPreferenceDisplayDialog(PreferenceFragment caller, Preference pref) {
- return getOuterParent().onPreferenceDisplayDialog(caller, pref);
- }
- }
- }
-
private class RootViewOnKeyListener implements View.OnKeyListener {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
- return handleBackPress();
+ return getChildFragmentManager().popBackStackImmediate();
} else {
return false;
}