1package androidx.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    ViewGroup rootView;
22    View mProgressBarView;
23    private Handler mHandler = new Handler();
24    boolean mEnableProgressBar = true;
25    boolean mUserProvidedProgressBar;
26    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            mProgressBarView = null;
82        }
83
84        mHandler.removeCallbacks(runnable);
85    }
86
87    /**
88     * Sets a custom view to be shown in place of the default {@link ProgressBar}. This
89     * view must have a parent. Once set, we maintain the visibility property of this view.
90     *
91     * @param progressBarView custom view that will be shown to indicate progress.
92     */
93    public void setProgressBarView(View progressBarView) {
94        if (progressBarView.getParent() == null) {
95            throw new IllegalArgumentException("Must have a parent");
96        }
97
98        this.mProgressBarView = progressBarView;
99        this.mProgressBarView.setVisibility(View.INVISIBLE);
100        mUserProvidedProgressBar = true;
101    }
102
103    /**
104     * Returns the initial delay.
105     */
106    public long getInitialDelay() {
107        return mInitialDelay;
108    }
109
110    /**
111     * Sets the initial delay. Progress bar will be shown after this delay has elapsed.
112     *
113     * @param initialDelay millisecond representing the initial delay.
114     */
115    public void setInitialDelay(long initialDelay) {
116        this.mInitialDelay = initialDelay;
117    }
118
119    /**
120     * Disables progress bar.
121     */
122    public void disableProgressBar() {
123        mEnableProgressBar = false;
124    }
125
126    /**
127     * Enables progress bar.
128     */
129    public void enableProgressBar() {
130        mEnableProgressBar = true;
131    }
132}
133