165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane/*
265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Copyright (C) 2014 The Android Open Source Project
365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane *
465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Licensed under the Apache License, Version 2.0 (the "License");
565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * you may not use this file except in compliance with the License.
665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * You may obtain a copy of the License at
765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane *
865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane *      http://www.apache.org/licenses/LICENSE-2.0
965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane *
1065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Unless required by applicable law or agreed to in writing, software
1165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * distributed under the License is distributed on an "AS IS" BASIS,
1265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * See the License for the specific language governing permissions and
1465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * limitations under the License.
1565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */
1665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
1765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lanepackage com.android.tv.settings.dialog.old;
1865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
1965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.app.Activity;
2065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.app.Fragment;
2165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.app.FragmentManager;
2265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.app.FragmentTransaction;
2365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.graphics.drawable.ColorDrawable;
2465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.Bundle;
2565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.view.View;
2665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.view.ViewGroup;
2765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.view.animation.Interpolator;
2865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
2965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.R;
3065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
3165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane/**
3265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane* A DialogFragment has 2 fragments, a content fragment and a list fragment.
3365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane* <p>
3465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane* Subclasses should override to supply the content fragment and list items.
3565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane* <p>
3665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane* The DialogFragment will handle animating in and out.
3765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane* <p>
3865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane* This class will use a default layout, but a custom layout can be provided by
3965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane* calling {@link #setLayoutProperties}
4065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane*/
4165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lanepublic class DialogFragment extends Fragment implements ActionAdapter.Listener, LiteFragment {
4265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
4365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private Activity mActivity;
446e995161147d9110d77ae1fe38b697e52891d3f2Tony Mantler    private final BaseDialogFragment mBase = new BaseDialogFragment(this);
4565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
4665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    @Override
4765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    public void onActionClicked(Action action) {
4865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        mBase.onActionClicked(getRealActivity(), action);
4965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
5065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
5165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    protected void disableEntryAnimation() {
5265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        mBase.disableEntryAnimation();
5365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
5465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
5565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    public void performEntryTransition() {
5665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        if (mBase.mFirstOnStart) {
5765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            mBase.mFirstOnStart = false;
5865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            // Once the subclass has setup its view hierarchy, we can perform an entry
5965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            // transition if specified by the intent.
6065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            Fragment fragment = getContentFragment();
6165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            if (fragment instanceof ContentFragment) {
6265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                ContentFragment cf = (ContentFragment) fragment;
6365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                mBase.performEntryTransition(getRealActivity(),
646e995161147d9110d77ae1fe38b697e52891d3f2Tony Mantler                        (ViewGroup) getRealActivity().findViewById(android.R.id.content),
6565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        cf.getIcon(), cf.getTitle(), cf.getDescription(), cf.getBreadCrumb());
6665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            }
6765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        }
6865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
6965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
7065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    /**
7165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * This method sets the layout property of this class. <br/>
7265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * Activities extending {@link DialogFragment} should call this method
7365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * before calling {@link #onCreate(Bundle)} if they want to have a
7465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * custom view.
7565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     *
7665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * @param contentAreaId id of the content area
7765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * @param actionAreaId id of the action area
7865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     */
7965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    protected void setLayoutProperties(int contentAreaId, int actionAreaId) {
8065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        mBase.setLayoutProperties(contentAreaId, actionAreaId);
8165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
8265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
8365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    /**
8465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * Animates a view.
8565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     *
8665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * @param v              view to animate
8765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * @param initAlpha      initial alpha
8865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * @param initTransX     initial translation in the X
8965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * @param delay          delay in ms
9065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * @param duration       duration in ms
9165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * @param interpolator   interpolator to be used, can be null
9265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * @param isIcon         if {@code true}, this is the main icon being moved
9365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     */
9465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    protected void prepareAndAnimateView(final View v, float initAlpha, float initTransX, int delay,
9565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            int duration, Interpolator interpolator, final boolean isIcon) {
9665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        mBase.prepareAndAnimateView(
9765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                v, initAlpha, initTransX, delay, duration, interpolator, isIcon);
9865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
9965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
10065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    /**
10165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * Called when intro animation is finished.
10265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * <p>
10365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * If a subclass is going to alter the view, should wait until this is called.
10465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     */
10565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    protected void onIntroAnimationFinished() {
10665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        mBase.onIntroAnimationFinished();
10765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
10865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
10965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    protected boolean isIntroAnimationInProgress() {
11065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        return mBase.isIntroAnimationInProgress();
11165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
11265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
11365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    protected ColorDrawable getBackgroundDrawable() {
11465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        return mBase.getBackgroundDrawable();
11565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
11665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
11765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    protected void setBackgroundDrawable(ColorDrawable drawable) {
11865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        mBase.setBackgroundDrawable(drawable);
11965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
12065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
12165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    /* ********************************************************************* */
12265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    /* Fragment related code below, cannot be placed into BaseDialogFragment */
12365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    /* ********************************************************************* */
12465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
12565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    public void setActivity(Activity act) {
12665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        mActivity = act;
12765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
12865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
12965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    /**
13065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * Capable of returning {@link Activity} prior to this Fragment being
13165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * attached to it's parent Activity.  Useful for getting the parent
13265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * Activity prior to {@link #onAttach(Activity)} being called.
13365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * @return parent {@link Activity}
13465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     */
13565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private Activity getRealActivity() {
13665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        return (mActivity != null ? mActivity : getActivity());
13765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
13865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
13965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    /**
14065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * Sets the content fragment into the view.
14165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     */
14265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    protected void setContentFragment(Fragment fragment) {
14365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        FragmentTransaction ft = getContentFragmentTransaction(fragment);
14465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        ft.commit();
14565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
14665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
14765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    /**
14865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * Sets the action fragment into the view.
14965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * <p>
15065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * If an action fragment currently exists, this will be added to the back stack.
15165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     */
15265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    protected void setActionFragment(Fragment fragment) {
15365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        setActionFragment(fragment, true);
15465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
15565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
15665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    /**
15765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * Sets the action fragment into the view.
15865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * <p>
15965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * If addToBackStack is true, and action fragment currently exists,
16065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * this will be added to the back stack.
16165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     */
16265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    protected void setActionFragment(Fragment fragment, boolean addToBackStack) {
16365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        FragmentTransaction ft = addActionFragmentToTransaction(fragment, null, addToBackStack,
16465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                getRealActivity().getFragmentManager());
16565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        ft.commit();
16665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
16765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
16865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    protected Fragment getActionFragment() {
16965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        return getRealActivity().getFragmentManager()
17065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                .findFragmentByTag(BaseDialogFragment.TAG_ACTION);
17165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
17265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
17365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    protected Fragment getContentFragment() {
17465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        return getRealActivity().getFragmentManager()
17565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                .findFragmentByTag(BaseDialogFragment.TAG_CONTENT);
17665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
17765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
17865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    /**
17965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * Set the content and action fragments in the same transaction.
18065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * <p>
18165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * If an action fragment currently exists, this will be added to the back stack.
18265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     */
18365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    protected void setContentAndActionFragments(Fragment contentFragment, Fragment actionFragment) {
18465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        setContentAndActionFragments(contentFragment, actionFragment, true);
18565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
18665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
18765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    /**
18865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * Set the content and action fragments in the same transaction.
18965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * <p>
19065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * If addToBackStack and an action fragment currently exists,
19165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * this will be added to the back stack.
19265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     */
19365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    protected void setContentAndActionFragments(Fragment contentFragment, Fragment actionFragment,
19465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            boolean addToBackStack) {
19565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        FragmentTransaction ft = getContentFragmentTransaction(contentFragment);
19665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        ft = addActionFragmentToTransaction(actionFragment, ft, addToBackStack,
19765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                getRealActivity().getFragmentManager());
19865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        ft.commit();
19965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
20065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
20165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    /**
20265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * Begins a fragment transaction to edit the content fragment.
20365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     */
20465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private FragmentTransaction getContentFragmentTransaction(Fragment fragment) {
20565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        FragmentManager fm = getRealActivity().getFragmentManager();
20665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        boolean hasContent = fm.findFragmentByTag(BaseDialogFragment.TAG_CONTENT) != null;
20765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        FragmentTransaction ft = fm.beginTransaction();
20865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
20965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        if (hasContent) {
21065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            addAnimations(ft);
21165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        }
21265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        ft.replace(mBase.mContentAreaId, fragment, BaseDialogFragment.TAG_CONTENT);
21365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        return ft;
21465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
21565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
21665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    /**
21765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * Adds an action fragment replacement to an existing fragment transaction, or creates one if
21865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * necessary.
21965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * <p>
22065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     * If an action fragment currently exists, this will be added to the back stack.
22165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane     */
22265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private FragmentTransaction addActionFragmentToTransaction(Fragment fragment,
22365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            FragmentTransaction ft, boolean addToBackStack, FragmentManager fm) {
22465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        if (ft == null) {
22565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            ft = fm.beginTransaction();
22665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        }
22765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        boolean hasActions = fm.findFragmentByTag(BaseDialogFragment.TAG_ACTION) != null;
22865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        if (hasActions) {
22965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            addAnimations(ft);
23065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            if (addToBackStack) {
23165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                ft.addToBackStack(null);
23265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            }
23365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        }
23465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        ft.replace(mBase.mActionAreaId, fragment, BaseDialogFragment.TAG_ACTION);
23565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
23665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        if (fragment instanceof ActionFragment) {
23765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            if (!((ActionFragment) fragment).hasListener()) {
23865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                ((ActionFragment) fragment).setListener(this);
23965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            }
24065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        }
24165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
24265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        return ft;
24365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
24465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
24565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    static void addAnimations(FragmentTransaction ft) {
24665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        ft.setCustomAnimations(R.anim.fragment_slide_left_in,
24765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                R.anim.fragment_slide_left_out, R.anim.fragment_slide_right_in,
24865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                R.anim.fragment_slide_right_out);
24965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
25065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane}
25165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
252