• 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.google.android.setupdesign.template;
18 
19 import android.content.res.ColorStateList;
20 import android.os.Build;
21 import android.os.Build.VERSION_CODES;
22 import androidx.annotation.Nullable;
23 import android.view.View;
24 import android.view.ViewStub;
25 import android.widget.ProgressBar;
26 import com.google.android.setupcompat.internal.TemplateLayout;
27 import com.google.android.setupcompat.template.Mixin;
28 import com.google.android.setupdesign.R;
29 
30 /** A {@link Mixin} for showing a progress bar. */
31 public class ProgressBarMixin implements Mixin {
32 
33   private final TemplateLayout templateLayout;
34 
35   @Nullable private ColorStateList color;
36 
37   /** @param layout The layout this mixin belongs to. */
ProgressBarMixin(TemplateLayout layout)38   public ProgressBarMixin(TemplateLayout layout) {
39     templateLayout = layout;
40   }
41 
42   /** @return True if the progress bar is currently shown. */
isShown()43   public boolean isShown() {
44     final View progressBar = templateLayout.findManagedViewById(R.id.sud_layout_progress);
45     return progressBar != null && progressBar.getVisibility() == View.VISIBLE;
46   }
47 
48   /**
49    * Sets whether the progress bar is shown. If the progress bar has not been inflated from the
50    * stub, this method will inflate the progress bar.
51    *
52    * @param shown True to show the progress bar, false to hide it.
53    */
setShown(boolean shown)54   public void setShown(boolean shown) {
55     if (shown) {
56       View progressBar = getProgressBar();
57       if (progressBar != null) {
58         progressBar.setVisibility(View.VISIBLE);
59       }
60     } else {
61       View progressBar = peekProgressBar();
62       if (progressBar != null) {
63         progressBar.setVisibility(View.GONE);
64       }
65     }
66   }
67 
68   /**
69    * Gets the progress bar in the layout. If the progress bar has not been used before, it will be
70    * installed (i.e. inflated from its view stub).
71    *
72    * @return The progress bar of this layout. May be null only if the template used doesn't have a
73    *     progress bar built-in.
74    */
getProgressBar()75   private ProgressBar getProgressBar() {
76     final View progressBar = peekProgressBar();
77     if (progressBar == null) {
78       final ViewStub progressBarStub =
79           (ViewStub) templateLayout.findManagedViewById(R.id.sud_layout_progress_stub);
80       if (progressBarStub != null) {
81         progressBarStub.inflate();
82       }
83       setColor(color);
84     }
85     return peekProgressBar();
86   }
87 
88   /**
89    * Gets the progress bar in the layout only if it has been installed. {@link #setShown(boolean)}
90    * should be called before this to ensure the progress bar is set up correctly.
91    *
92    * @return The progress bar of this layout, or null if the progress bar is not installed. The null
93    *     case can happen either if {@link #setShown(boolean)} with true was not called before this,
94    *     or if the template does not contain a progress bar.
95    */
peekProgressBar()96   public ProgressBar peekProgressBar() {
97     return (ProgressBar) templateLayout.findManagedViewById(R.id.sud_layout_progress);
98   }
99 
100   /** Sets the color of the indeterminate progress bar. This method is a no-op on SDK < 21. */
setColor(@ullable ColorStateList color)101   public void setColor(@Nullable ColorStateList color) {
102     this.color = color;
103     if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
104       final ProgressBar bar = peekProgressBar();
105       if (bar != null) {
106         bar.setIndeterminateTintList(color);
107         if (Build.VERSION.SDK_INT >= VERSION_CODES.M || color != null) {
108           // There is a bug in Lollipop where setting the progress tint color to null
109           // will crash with "java.lang.NullPointerException: Attempt to invoke virtual
110           // method 'int android.graphics.Paint.getAlpha()' on a null object reference"
111           // at android.graphics.drawable.NinePatchDrawable.draw(:250)
112           // The bug doesn't affect ProgressBar on M because it uses ShapeDrawable instead
113           // of NinePatchDrawable. (commit 6a8253fdc9f4574c28b4beeeed90580ffc93734a)
114           bar.setProgressBackgroundTintList(color);
115         }
116       }
117     }
118   }
119 
120   /**
121    * @return The color previously set in {@link #setColor(ColorStateList)}, or null if the color is
122    *     not set. In case of null, the color of the progress bar will be inherited from the theme.
123    */
124   @Nullable
getColor()125   public ColorStateList getColor() {
126     return color;
127   }
128 }
129