Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0c24a551 authored by Adam Powell's avatar Adam Powell
Browse files

Fix bug 3156280 - Fix several issues with tab navigation in action bars.

Add the ability to restrict a FragmentTransaction's ability to be
added to the back stack. (It doesn't make sense for tabs or other
scenarios to allow this.)

Change-Id: I8fa2edb5f35c365e2483010ad13eb9993f5e6570
parent 079e2357
Loading
Loading
Loading
Loading
+33 −0
Original line number Original line Diff line number Diff line
@@ -19525,6 +19525,17 @@
<parameter name="index" type="int">
<parameter name="index" type="int">
</parameter>
</parameter>
</method>
</method>
<method name="getTabCount"
 return="int"
 abstract="true"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
</method>
<method name="getTitle"
<method name="getTitle"
 return="java.lang.CharSequence"
 return="java.lang.CharSequence"
 abstract="true"
 abstract="true"
@@ -28322,6 +28333,17 @@
 visibility="public"
 visibility="public"
>
>
</method>
</method>
<method name="disallowAddToBackStack"
 return="android.app.FragmentTransaction"
 abstract="true"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
</method>
<method name="hide"
<method name="hide"
 return="android.app.FragmentTransaction"
 return="android.app.FragmentTransaction"
 abstract="true"
 abstract="true"
@@ -28335,6 +28357,17 @@
<parameter name="fragment" type="android.app.Fragment">
<parameter name="fragment" type="android.app.Fragment">
</parameter>
</parameter>
</method>
</method>
<method name="isAddToBackStackAllowed"
 return="boolean"
 abstract="true"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
</method>
<method name="isEmpty"
<method name="isEmpty"
 return="boolean"
 return="boolean"
 abstract="true"
 abstract="true"
+12 −3
Original line number Original line Diff line number Diff line
@@ -477,6 +477,12 @@ public abstract class ActionBar {
     */
     */
    public abstract Tab getTabAt(int index);
    public abstract Tab getTabAt(int index);


    /**
     * Returns the number of tabs currently registered with the action bar.
     * @return Tab count
     */
    public abstract int getTabCount();

    /**
    /**
     * Retrieve the current height of the ActionBar.
     * Retrieve the current height of the ActionBar.
     *
     *
@@ -626,7 +632,8 @@ public abstract class ActionBar {
         * @param tab The tab that was selected
         * @param tab The tab that was selected
         * @param ft A {@link FragmentTransaction} for queuing fragment operations to execute
         * @param ft A {@link FragmentTransaction} for queuing fragment operations to execute
         *        during a tab switch. The previous tab's unselect and this tab's select will be
         *        during a tab switch. The previous tab's unselect and this tab's select will be
         *        executed in a single transaction.
         *        executed in a single transaction. This FragmentTransaction does not support
         *        being added to the back stack.
         */
         */
        public void onTabSelected(Tab tab, FragmentTransaction ft);
        public void onTabSelected(Tab tab, FragmentTransaction ft);


@@ -636,7 +643,8 @@ public abstract class ActionBar {
         * @param tab The tab that was unselected
         * @param tab The tab that was unselected
         * @param ft A {@link FragmentTransaction} for queuing fragment operations to execute
         * @param ft A {@link FragmentTransaction} for queuing fragment operations to execute
         *        during a tab switch. This tab's unselect and the newly selected tab's select
         *        during a tab switch. This tab's unselect and the newly selected tab's select
         *        will be executed in a single transaction.
         *        will be executed in a single transaction. This FragmentTransaction does not
         *        support being added to the back stack.
         */
         */
        public void onTabUnselected(Tab tab, FragmentTransaction ft);
        public void onTabUnselected(Tab tab, FragmentTransaction ft);


@@ -646,7 +654,8 @@ public abstract class ActionBar {
         *
         *
         * @param tab The tab that was reselected.
         * @param tab The tab that was reselected.
         * @param ft A {@link FragmentTransaction} for queuing fragment operations to execute
         * @param ft A {@link FragmentTransaction} for queuing fragment operations to execute
         *        once this method returns.
         *        once this method returns. This FragmentTransaction does not support
         *        being added to the back stack.
         */
         */
        public void onTabReselected(Tab tab, FragmentTransaction ft);
        public void onTabReselected(Tab tab, FragmentTransaction ft);
    }
    }
+18 −0
Original line number Original line Diff line number Diff line
@@ -186,6 +186,7 @@ final class BackStackRecord implements FragmentTransaction,
    int mTransition;
    int mTransition;
    int mTransitionStyle;
    int mTransitionStyle;
    boolean mAddToBackStack;
    boolean mAddToBackStack;
    boolean mAllowAddToBackStack = true;
    String mName;
    String mName;
    boolean mCommitted;
    boolean mCommitted;
    int mIndex;
    int mIndex;
@@ -346,11 +347,28 @@ final class BackStackRecord implements FragmentTransaction,
    }
    }


    public FragmentTransaction addToBackStack(String name) {
    public FragmentTransaction addToBackStack(String name) {
        if (!mAllowAddToBackStack) {
            throw new IllegalStateException(
                    "This FragmentTransaction is not allowed to be added to the back stack.");
        }
        mAddToBackStack = true;
        mAddToBackStack = true;
        mName = name;
        mName = name;
        return this;
        return this;
    }
    }


    public boolean isAddToBackStackAllowed() {
        return mAllowAddToBackStack;
    }

    public FragmentTransaction disallowAddToBackStack() {
        if (mAddToBackStack) {
            throw new IllegalStateException(
                    "This transaction is already being added to the back stack");
        }
        mAllowAddToBackStack = false;
        return this;
    }

    public FragmentTransaction setBreadCrumbTitle(int res) {
    public FragmentTransaction setBreadCrumbTitle(int res) {
        mBreadCrumbTitleRes = res;
        mBreadCrumbTitleRes = res;
        mBreadCrumbTitleText = null;
        mBreadCrumbTitleText = null;
+16 −0
Original line number Original line Diff line number Diff line
@@ -143,6 +143,22 @@ public interface FragmentTransaction {
     */
     */
    public FragmentTransaction addToBackStack(String name);
    public FragmentTransaction addToBackStack(String name);


    /**
     * Returns true if this FragmentTransaction is allowed to be added to the back
     * stack. If this method would return false, {@link #addToBackStack(String)}
     * will throw {@link IllegalStateException}.
     *
     * @return True if {@link #addToBackStack(String)} is permitted on this transaction.
     */
    public boolean isAddToBackStackAllowed();

    /**
     * Disallow calls to {@link #addToBackStack(String)}. Any future calls to
     * addToBackStack will throw {@link IllegalStateException}. If addToBackStack
     * has already been called, this method will throw IllegalStateException.
     */
    public FragmentTransaction disallowAddToBackStack();

    /**
    /**
     * Set the full title to show as a bread crumb when this transaction
     * Set the full title to show as a bread crumb when this transaction
     * is on the back stack, as used by {@link FragmentBreadCrumbs}.
     * is on the back stack, as used by {@link FragmentBreadCrumbs}.
+57 −2
Original line number Original line Diff line number Diff line
@@ -65,12 +65,15 @@ public class ActionBarImpl extends ActionBar {
    private ArrayList<TabImpl> mTabs = new ArrayList<TabImpl>();
    private ArrayList<TabImpl> mTabs = new ArrayList<TabImpl>();


    private TabImpl mSelectedTab;
    private TabImpl mSelectedTab;
    private int mSavedTabPosition = INVALID_POSITION;
    
    
    private ActionMode mActionMode;
    private ActionMode mActionMode;
    
    
    private static final int CONTEXT_DISPLAY_NORMAL = 0;
    private static final int CONTEXT_DISPLAY_NORMAL = 0;
    private static final int CONTEXT_DISPLAY_SPLIT = 1;
    private static final int CONTEXT_DISPLAY_SPLIT = 1;
    
    
    private static final int INVALID_POSITION = -1;

    private int mContextDisplayMode;
    private int mContextDisplayMode;


    private boolean mClosingContext;
    private boolean mClosingContext;
@@ -183,6 +186,8 @@ public class ActionBarImpl extends ActionBar {
            selectTab(null);
            selectTab(null);
        }
        }
        mTabs.clear();
        mTabs.clear();
        mActionView.removeAllTabs();
        mSavedTabPosition = INVALID_POSITION;
    }
    }


    public void setTitle(CharSequence title) {
    public void setTitle(CharSequence title) {
@@ -310,6 +315,8 @@ public class ActionBarImpl extends ActionBar {


    @Override
    @Override
    public void removeTabAt(int position) {
    public void removeTabAt(int position) {
        int selectedTabPosition = mSelectedTab != null
                ? mSelectedTab.getPosition() : mSavedTabPosition;
        mActionView.removeTabAt(position);
        mActionView.removeTabAt(position);
        mTabs.remove(position);
        mTabs.remove(position);


@@ -318,8 +325,10 @@ public class ActionBarImpl extends ActionBar {
            mTabs.get(i).setPosition(i);
            mTabs.get(i).setPosition(i);
        }
        }


        if (selectedTabPosition == position) {
            selectTab(mTabs.isEmpty() ? null : mTabs.get(Math.max(0, position - 1)));
            selectTab(mTabs.isEmpty() ? null : mTabs.get(Math.max(0, position - 1)));
        }
        }
    }


    @Override
    @Override
    public void setTabNavigationMode() {
    public void setTabNavigationMode() {
@@ -333,7 +342,13 @@ public class ActionBarImpl extends ActionBar {


    @Override
    @Override
    public void selectTab(Tab tab) {
    public void selectTab(Tab tab) {
        final FragmentTransaction trans = mActivity.getFragmentManager().openTransaction();
        if (getNavigationMode() != NAVIGATION_MODE_TABS) {
            mSavedTabPosition = tab != null ? tab.getPosition() : INVALID_POSITION;
            return;
        }

        final FragmentTransaction trans = mActivity.getFragmentManager().openTransaction()
                .disallowAddToBackStack();


        if (mSelectedTab == tab) {
        if (mSelectedTab == tab) {
            if (mSelectedTab != null) {
            if (mSelectedTab != null) {
@@ -622,13 +637,53 @@ public class ActionBarImpl extends ActionBar {
        }
        }
    }
    }


    @Override
    public int getTabCount() {
        return mTabs.size();
    }

    @Override
    @Override
    public void setNavigationMode(int mode) {
    public void setNavigationMode(int mode) {
        final int oldMode = mActionView.getNavigationMode();
        switch (oldMode) {
            case NAVIGATION_MODE_TABS:
                mSavedTabPosition = getSelectedNavigationIndex();
                selectTab(null);
                break;
        }
        mActionView.setNavigationMode(mode);
        mActionView.setNavigationMode(mode);
        switch (mode) {
            case NAVIGATION_MODE_TABS:
                if (mSavedTabPosition != INVALID_POSITION) {
                    setSelectedNavigationItem(mSavedTabPosition);
                    mSavedTabPosition = INVALID_POSITION;
                }
                break;
        }
    }
    }


    @Override
    @Override
    public Tab getTabAt(int index) {
    public Tab getTabAt(int index) {
        return mTabs.get(index);
        return mTabs.get(index);
    }
    }

    /**
     * This fragment is added when we're keeping a back stack in a tab switch
     * transaction. We use it to change the selected tab in the action bar view
     * when we back out.
     */
    private class SwitchSelectedTabViewFragment extends Fragment {
        private int mSelectedTabIndex;

        public SwitchSelectedTabViewFragment(int oldSelectedTab) {
            mSelectedTabIndex = oldSelectedTab;
        }

        @Override
        public void onDetach() {
            if (mSelectedTabIndex >= 0 && mSelectedTabIndex < getTabCount()) {
                mActionView.setTabSelected(mSelectedTabIndex);
            }
        }
    }
}
}
Loading