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