1package android.support.v17.leanback.app;
2
3import android.os.Handler;
4import android.view.Gravity;
5import android.view.View;
6import android.view.ViewGroup;
7import android.widget.FrameLayout;
8import android.widget.ProgressBar;
9
10/**
11 * Manager for showing/hiding progress bar widget. This class lets user specify an initial
12 * delay after which the progress bar will be shown. This is currently being used in
13 * {@link BrowseFragment} & {@link VerticalGridFragment} to show {@link ProgressBar}
14 * while the data is being loaded.
15 */
16public final class ProgressBarManager {
17    // Default delay for progress bar widget.
18    private static final long DEFAULT_PROGRESS_BAR_DELAY = 1000;
19
20    private long mInitialDelay = DEFAULT_PROGRESS_BAR_DELAY;
21    private ViewGroup rootView;
22    private View mProgressBarView;
23    private Handler mHandler = new Handler();
24    private boolean mEnableProgressBar = true;
25    private boolean mUserProvidedProgressBar;
26    private boolean mIsShowing;
27
28    private Runnable runnable = new Runnable() {
29        @Override
30        public void run() {
31            if (!mEnableProgressBar || (!mUserProvidedProgressBar && rootView == null)) {
32                return;
33            }
34
35            if (mIsShowing) {
36                if (mProgressBarView == null) {
37                    mProgressBarView = new ProgressBar(
38                            rootView.getContext(), null, android.R.attr.progressBarStyleLarge);
39                    FrameLayout.LayoutParams progressBarParams = new FrameLayout.LayoutParams(
40                            FrameLayout.LayoutParams.WRAP_CONTENT,
41                            FrameLayout.LayoutParams.WRAP_CONTENT);
42                    progressBarParams.gravity = Gravity.CENTER;
43                    rootView.addView(mProgressBarView, progressBarParams);
44                } else if (mUserProvidedProgressBar) {
45                    mProgressBarView.setVisibility(View.VISIBLE);
46                }
47            }
48        }
49    };
50
51    /**
52     * Sets the root view on which the progress bar will be attached. This class assumes the
53     * root view to be {@link FrameLayout} in order to position the progress bar widget
54     * in the center of the screen.
55     *
56     * @param rootView view that will contain the progress bar.
57     */
58    public void setRootView(ViewGroup rootView) {
59        this.rootView = rootView;
60    }
61
62    /**
63     * Displays the progress bar.
64     */
65    public void show() {
66        if (mEnableProgressBar) {
67            mIsShowing = true;
68            mHandler.postDelayed(runnable, mInitialDelay);
69        }
70    }
71
72    /**
73     * Hides the progress bar.
74     */
75    public void hide() {
76        mIsShowing = false;
77        if (mUserProvidedProgressBar) {
78            mProgressBarView.setVisibility(View.INVISIBLE);
79        } else if (mProgressBarView != null) {
80            rootView.removeView(mProgressBarView);
81        }
82
83        mHandler.removeCallbacks(runnable);
84    }
85
86    /**
87     * Sets a custom view to be shown in place of the default {@link ProgressBar}. This
88     * view must have a parent. Once set, we maintain the visibility property of this view.
89     *
90     * @param progressBarView custom view that will be shown to indicate progress.
91     */
92    public void setProgressBarView(View progressBarView) {
93        if (progressBarView.getParent() == null) {
94            throw new IllegalArgumentException("Must have a parent");
95        }
96
97        this.mProgressBarView = progressBarView;
98        this.mProgressBarView.setVisibility(View.INVISIBLE);
99        mUserProvidedProgressBar = true;
100    }
101
102    /**
103     * Returns the initial delay.
104     */
105    public long getInitialDelay() {
106        return mInitialDelay;
107    }
108
109    /**
110     * Sets the initial delay. Progress bar will be shown after this delay has elapsed.
111     *
112     * @param initialDelay millisecond representing the initial delay.
113     */
114    public void setInitialDelay(long initialDelay) {
115        this.mInitialDelay = initialDelay;
116    }
117
118    /**
119     * Disables progress bar.
120     */
121    public void disableProgressBar() {
122        mEnableProgressBar = false;
123    }
124
125    /**
126     * Enables progress bar.
127     */
128    public void enableProgressBar() {
129        mEnableProgressBar = true;
130    }
131}
132