1/* This file is auto-generated from BaseFragment.java.  DO NOT MODIFY. */
2
3/*
4 * Copyright (C) 2014 The Android Open Source Project
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
7 * in compliance with the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software distributed under the License
12 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
13 * or implied. See the License for the specific language governing permissions and limitations under
14 * the License.
15 */
16package android.support.v17.leanback.app;
17
18import android.support.v4.app.Fragment;
19import android.os.Bundle;
20import android.support.v17.leanback.R;
21import android.support.v17.leanback.transition.TransitionHelper;
22import android.support.v17.leanback.transition.TransitionListener;
23import android.view.View;
24import android.view.ViewTreeObserver;
25
26/**
27 * @hide
28 */
29class BaseSupportFragment extends Fragment {
30
31    private boolean mEntranceTransitionEnabled = false;
32    private boolean mStartEntranceTransitionPending = false;
33    private Object mEntranceTransition;
34
35    static TransitionHelper sTransitionHelper = TransitionHelper.getInstance();
36
37    @Override
38    public void onViewCreated(View view, Bundle savedInstanceState) {
39        super.onViewCreated(view, savedInstanceState);
40        if (mStartEntranceTransitionPending) {
41            mStartEntranceTransitionPending = false;
42            startEntranceTransition();
43        }
44    }
45
46    /**
47     * Enables entrance transition.<p>
48     * Entrance transition is the standard slide-in transition that shows rows of data in
49     * browse screen and details screen.
50     * <p>
51     * The method is ignored before LOLLIPOP (API21).
52     * <p>
53     * This method must be called in or
54     * before onCreate().  Typically entrance transition should be enabled when savedInstance is
55     * null so that fragment restored from instanceState does not run an extra entrance transition.
56     * When the entrance transition is enabled, the fragment will make headers and content
57     * hidden initially.
58     * When data of rows are ready, app must call {@link #startEntranceTransition()} to kick off
59     * the transition, otherwise the rows will be invisible forever.
60     * <p>
61     * It is similar to android:windowsEnterTransition and can be considered a late-executed
62     * android:windowsEnterTransition controlled by app.  There are two reasons that app needs it:
63     * <li> Workaround the problem that activity transition is not available between launcher and
64     * app.  Browse activity must programmatically start the slide-in transition.</li>
65     * <li> Separates DetailsOverviewRow transition from other rows transition.  So that
66     * the DetailsOverviewRow transition can be executed earlier without waiting for all rows
67     * to be loaded.</li>
68     * <p>
69     * Transition object is returned by createEntranceTransition().  Typically the app does not need
70     * override the default transition that browse and details provides.
71     */
72    public void prepareEntranceTransition() {
73        if (TransitionHelper.systemSupportsEntranceTransitions()) {
74            mEntranceTransitionEnabled = true;
75        }
76    }
77
78    /**
79     * Return true if entrance transition is enabled and not started yet.
80     * Entrance transition can only be executed once and isEntranceTransitionEnabled()
81     * is reset to false after entrance transition is started.
82     */
83    boolean isEntranceTransitionEnabled() {
84        return mEntranceTransitionEnabled;
85    }
86
87    /**
88     * Create entrance transition.  Subclass can override to load transition from
89     * resource or construct manually.  Typically app does not need to
90     * override the default transition that browse and details provides.
91     */
92    protected Object createEntranceTransition() {
93        return null;
94    }
95
96    /**
97     * Run entrance transition.  Subclass may use TransitionManager to perform
98     * go(Scene) or beginDelayedTransition().  App should not override the default
99     * implementation of browse and details fragment.
100     */
101    protected void runEntranceTransition(Object entranceTransition) {
102    }
103
104    /**
105     * Callback when entrance transition is started.
106     */
107    protected void onEntranceTransitionStart() {
108    }
109
110    /**
111     * Callback when entrance transition is ended.
112     */
113    protected void onEntranceTransitionEnd() {
114    }
115
116    /**
117     * When fragment finishes loading data, it should call startEntranceTransition()
118     * to execute the entrance transition.
119     * startEntranceTransition() will start transition only if both two conditions
120     * are satisfied:
121     * <li> prepareEntranceTransition() was called.</li>
122     * <li> has not executed entrance transition yet.</li>
123     * <p>
124     * If startEntranceTransition() is called before onViewCreated(), it will be pending
125     * and executed when view is created.
126     */
127    public void startEntranceTransition() {
128        if (!mEntranceTransitionEnabled || mEntranceTransition != null) {
129            return;
130        }
131        // if view is not created yet, delay until onViewCreated()
132        if (getView() == null) {
133            mStartEntranceTransitionPending = true;
134            return;
135        }
136        // wait till views get their initial position before start transition
137        final View view = getView();
138        view.getViewTreeObserver().addOnPreDrawListener(
139                new ViewTreeObserver.OnPreDrawListener() {
140            @Override
141            public boolean onPreDraw() {
142                view.getViewTreeObserver().removeOnPreDrawListener(this);
143                internalCreateEntranceTransition();
144                mEntranceTransitionEnabled = false;
145                runEntranceTransition(mEntranceTransition);
146                return false;
147            }
148        });
149        view.invalidate();
150    }
151
152    void internalCreateEntranceTransition() {
153        mEntranceTransition = createEntranceTransition();
154        if (mEntranceTransition == null) {
155            return;
156        }
157        sTransitionHelper.setTransitionListener(mEntranceTransition, new TransitionListener() {
158            @Override
159            public void onTransitionStart(Object transition) {
160                onEntranceTransitionStart();
161            }
162            @Override
163            public void onTransitionEnd(Object transition) {
164                mEntranceTransition = null;
165                onEntranceTransitionEnd();
166            }
167        });
168    }
169}
170