• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings.widget;
18 
19 import android.os.Handler;
20 import android.os.Looper;
21 import android.view.View;
22 import android.view.animation.Animation;
23 import android.view.animation.AnimationUtils;
24 
25 import androidx.annotation.Nullable;
26 
27 /**
28  * A helper class that manages show/hide loading spinner, content view and empty view (optional).
29  */
30 public class LoadingViewController {
31 
32     private static final long DELAY_SHOW_LOADING_CONTAINER_THRESHOLD_MS = 100L;
33 
34     private final Handler mFgHandler;
35     private final View mLoadingView;
36     private final View mContentView;
37     private final View mEmptyView;
38 
LoadingViewController(View loadingView, View contentView)39     public LoadingViewController(View loadingView, View contentView) {
40         this(loadingView, contentView, null /* emptyView*/);
41     }
42 
LoadingViewController(View loadingView, View contentView, @Nullable View emptyView)43     public LoadingViewController(View loadingView, View contentView, @Nullable View emptyView) {
44         mLoadingView = loadingView;
45         mContentView = contentView;
46         mEmptyView = emptyView;
47         mFgHandler = new Handler(Looper.getMainLooper());
48     }
49 
50     private Runnable mShowLoadingContainerRunnable = new Runnable() {
51         public void run() {
52             showLoadingView();
53         }
54     };
55 
56     /**
57      *  Shows content view and hides loading view & empty view.
58      */
showContent(boolean animate)59     public void showContent(boolean animate) {
60         // Cancel any pending task to show the loading animation and show the list of
61         // apps directly.
62         mFgHandler.removeCallbacks(mShowLoadingContainerRunnable);
63         handleLoadingContainer(true /* showContent */, false /* showEmpty*/, animate);
64     }
65 
66     /**
67      *  Shows empty view and hides loading view & content view.
68      */
showEmpty(boolean animate)69     public void showEmpty(boolean animate) {
70         if (mEmptyView == null) {
71             return;
72         }
73 
74         // Cancel any pending task to show the loading animation and show the list of
75         // apps directly.
76         mFgHandler.removeCallbacks(mShowLoadingContainerRunnable);
77         handleLoadingContainer(false /* showContent */, true /* showEmpty */, animate);
78     }
79 
80     /**
81      *  Shows loading view and hides content view & empty view.
82      */
showLoadingView()83     public void showLoadingView() {
84         handleLoadingContainer(false /* showContent */, false /* showEmpty */, false /* animate */);
85     }
86 
showLoadingViewDelayed()87     public void showLoadingViewDelayed() {
88         mFgHandler.postDelayed(
89                 mShowLoadingContainerRunnable, DELAY_SHOW_LOADING_CONTAINER_THRESHOLD_MS);
90     }
91 
handleLoadingContainer(boolean showContent, boolean showEmpty, boolean animate)92     private void handleLoadingContainer(boolean showContent, boolean showEmpty, boolean animate) {
93         handleLoadingContainer(mLoadingView, mContentView, mEmptyView,
94                 showContent, showEmpty, animate);
95     }
96 
97     /**
98      * Show/hide loading view and content view.
99      *
100      * @param loading The loading spinner view
101      * @param content The content view
102      * @param done    If true, content is set visible and loading is set invisible.
103      * @param animate Whether or not content/loading views should animate in/out.
104      */
handleLoadingContainer(View loading, View content, boolean done, boolean animate)105     public static void handleLoadingContainer(View loading, View content, boolean done,
106             boolean animate) {
107         setViewShown(loading, !done, animate);
108         setViewShown(content, done, animate);
109     }
110 
111     /**
112      * Show/hide loading view and content view and empty view.
113      *
114      * @param loading The loading spinner view
115      * @param content The content view
116      * @param empty The empty view shows no item summary to users.
117      * @param showContent    If true, content is set visible and loading is set invisible.
118      * @param showEmpty    If true, empty is set visible and loading is set invisible.
119      * @param animate Whether or not content/loading views should animate in/out.
120      */
handleLoadingContainer(View loading, View content, View empty, boolean showContent, boolean showEmpty, boolean animate)121     public static void handleLoadingContainer(View loading, View content, View empty,
122             boolean showContent, boolean showEmpty, boolean animate) {
123         if (empty != null) {
124             setViewShown(empty, showEmpty, animate);
125         }
126         setViewShown(content, showContent, animate);
127         setViewShown(loading, !showContent && !showEmpty, animate);
128     }
129 
setViewShown(final View view, boolean shown, boolean animate)130     private static void setViewShown(final View view, boolean shown, boolean animate) {
131         if (animate) {
132             Animation animation = AnimationUtils.loadAnimation(view.getContext(),
133                     shown ? android.R.anim.fade_in : android.R.anim.fade_out);
134             if (shown) {
135                 view.setVisibility(View.VISIBLE);
136             } else {
137                 animation.setAnimationListener(new Animation.AnimationListener() {
138                     @Override
139                     public void onAnimationStart(Animation animation) {
140                     }
141 
142                     @Override
143                     public void onAnimationRepeat(Animation animation) {
144                     }
145 
146                     @Override
147                     public void onAnimationEnd(Animation animation) {
148                         view.setVisibility(View.INVISIBLE);
149                     }
150                 });
151             }
152             view.startAnimation(animation);
153         } else {
154             view.clearAnimation();
155             view.setVisibility(shown ? View.VISIBLE : View.INVISIBLE);
156         }
157     }
158 }
159