• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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;
18 
19 import android.annotation.TargetApi;
20 import android.content.Context;
21 import android.content.res.ColorStateList;
22 import android.content.res.TypedArray;
23 import android.graphics.drawable.ColorDrawable;
24 import android.graphics.drawable.Drawable;
25 import android.os.Build;
26 import android.os.Build.VERSION_CODES;
27 import android.support.annotation.LayoutRes;
28 import android.support.annotation.NonNull;
29 import android.support.annotation.Nullable;
30 import android.util.AttributeSet;
31 import android.view.LayoutInflater;
32 import android.view.View;
33 import android.view.ViewGroup;
34 import android.view.ViewStub;
35 import android.widget.ProgressBar;
36 import android.widget.ScrollView;
37 import android.widget.TextView;
38 
39 import com.android.setupwizardlib.template.ButtonFooterMixin;
40 import com.android.setupwizardlib.template.ColoredHeaderMixin;
41 import com.android.setupwizardlib.template.HeaderMixin;
42 import com.android.setupwizardlib.template.IconMixin;
43 import com.android.setupwizardlib.template.ProgressBarMixin;
44 import com.android.setupwizardlib.template.RequireScrollMixin;
45 import com.android.setupwizardlib.template.ScrollViewScrollHandlingDelegate;
46 import com.android.setupwizardlib.view.StatusBarBackgroundLayout;
47 
48 /**
49  * Layout for the GLIF theme used in Setup Wizard for N.
50  *
51  * <p>Example usage:
52  * <pre>{@code
53  * &lt;com.android.setupwizardlib.GlifLayout
54  *     xmlns:android="http://schemas.android.com/apk/res/android"
55  *     xmlns:app="http://schemas.android.com/apk/res-auto"
56  *     android:layout_width="match_parent"
57  *     android:layout_height="match_parent"
58  *     android:icon="@drawable/my_icon"
59  *     app:suwHeaderText="@string/my_title">
60  *
61  *     &lt;!-- Content here -->
62  *
63  * &lt;/com.android.setupwizardlib.GlifLayout>
64  * }</pre>
65  */
66 public class GlifLayout extends TemplateLayout {
67 
68     private static final String TAG = "GlifLayout";
69 
70     private ColorStateList mPrimaryColor;
71 
72     private boolean mBackgroundPatterned = true;
73 
74     /**
75      * The color of the background. If null, the color will inherit from mPrimaryColor.
76      */
77     @Nullable
78     private ColorStateList mBackgroundBaseColor;
79 
GlifLayout(Context context)80     public GlifLayout(Context context) {
81         this(context, 0, 0);
82     }
83 
GlifLayout(Context context, int template)84     public GlifLayout(Context context, int template) {
85         this(context, template, 0);
86     }
87 
GlifLayout(Context context, int template, int containerId)88     public GlifLayout(Context context, int template, int containerId) {
89         super(context, template, containerId);
90         init(null, R.attr.suwLayoutTheme);
91     }
92 
GlifLayout(Context context, AttributeSet attrs)93     public GlifLayout(Context context, AttributeSet attrs) {
94         super(context, attrs);
95         init(attrs, R.attr.suwLayoutTheme);
96     }
97 
98     @TargetApi(VERSION_CODES.HONEYCOMB)
GlifLayout(Context context, AttributeSet attrs, int defStyleAttr)99     public GlifLayout(Context context, AttributeSet attrs, int defStyleAttr) {
100         super(context, attrs, defStyleAttr);
101         init(attrs, defStyleAttr);
102     }
103 
104     // All the constructors delegate to this init method. The 3-argument constructor is not
105     // available in LinearLayout before v11, so call super with the exact same arguments.
init(AttributeSet attrs, int defStyleAttr)106     private void init(AttributeSet attrs, int defStyleAttr) {
107         registerMixin(HeaderMixin.class, new ColoredHeaderMixin(this, attrs, defStyleAttr));
108         registerMixin(IconMixin.class, new IconMixin(this, attrs, defStyleAttr));
109         registerMixin(ProgressBarMixin.class, new ProgressBarMixin(this));
110         registerMixin(ButtonFooterMixin.class, new ButtonFooterMixin(this));
111         final RequireScrollMixin requireScrollMixin = new RequireScrollMixin(this);
112         registerMixin(RequireScrollMixin.class, requireScrollMixin);
113 
114         final ScrollView scrollView = getScrollView();
115         if (scrollView != null) {
116             requireScrollMixin.setScrollHandlingDelegate(
117                     new ScrollViewScrollHandlingDelegate(requireScrollMixin, scrollView));
118         }
119 
120         TypedArray a = getContext().obtainStyledAttributes(attrs,
121                 R.styleable.SuwGlifLayout, defStyleAttr, 0);
122 
123         ColorStateList primaryColor =
124                 a.getColorStateList(R.styleable.SuwGlifLayout_suwColorPrimary);
125         if (primaryColor != null) {
126             setPrimaryColor(primaryColor);
127         }
128 
129         ColorStateList backgroundColor =
130                 a.getColorStateList(R.styleable.SuwGlifLayout_suwBackgroundBaseColor);
131         setBackgroundBaseColor(backgroundColor);
132 
133         boolean backgroundPatterned =
134                 a.getBoolean(R.styleable.SuwGlifLayout_suwBackgroundPatterned, true);
135         setBackgroundPatterned(backgroundPatterned);
136 
137         final int footer = a.getResourceId(R.styleable.SuwGlifLayout_suwFooter, 0);
138         if (footer != 0) {
139             inflateFooter(footer);
140         }
141 
142         a.recycle();
143     }
144 
145     @Override
onInflateTemplate(LayoutInflater inflater, @LayoutRes int template)146     protected View onInflateTemplate(LayoutInflater inflater, @LayoutRes int template) {
147         if (template == 0) {
148             template = R.layout.suw_glif_template;
149         }
150         return inflateTemplate(inflater, R.style.SuwThemeGlif_Light, template);
151     }
152 
153     @Override
findContainer(int containerId)154     protected ViewGroup findContainer(int containerId) {
155         if (containerId == 0) {
156             containerId = R.id.suw_layout_content;
157         }
158         return super.findContainer(containerId);
159     }
160 
161     /**
162      * Sets the footer of the layout, which is at the bottom of the content area outside the
163      * scrolling container. The footer can only be inflated once per layout.
164      *
165      * @param footer The layout to be inflated as footer.
166      * @return The root of the inflated footer view.
167      */
inflateFooter(@ayoutRes int footer)168     public View inflateFooter(@LayoutRes int footer) {
169         ViewStub footerStub = (ViewStub) findManagedViewById(R.id.suw_layout_footer);
170         footerStub.setLayoutResource(footer);
171         return footerStub.inflate();
172     }
173 
getScrollView()174     public ScrollView getScrollView() {
175         final View view = findManagedViewById(R.id.suw_scroll_view);
176         return view instanceof ScrollView ? (ScrollView) view : null;
177     }
178 
getHeaderTextView()179     public TextView getHeaderTextView() {
180         return getMixin(HeaderMixin.class).getTextView();
181     }
182 
setHeaderText(int title)183     public void setHeaderText(int title) {
184         getMixin(HeaderMixin.class).setText(title);
185     }
186 
setHeaderText(CharSequence title)187     public void setHeaderText(CharSequence title) {
188         getMixin(HeaderMixin.class).setText(title);
189     }
190 
getHeaderText()191     public CharSequence getHeaderText() {
192         return getMixin(HeaderMixin.class).getText();
193     }
194 
setHeaderColor(ColorStateList color)195     public void setHeaderColor(ColorStateList color) {
196         final ColoredHeaderMixin mixin = (ColoredHeaderMixin) getMixin(HeaderMixin.class);
197         mixin.setColor(color);
198     }
199 
getHeaderColor()200     public ColorStateList getHeaderColor() {
201         final ColoredHeaderMixin mixin = (ColoredHeaderMixin) getMixin(HeaderMixin.class);
202         return mixin.getColor();
203     }
204 
setIcon(Drawable icon)205     public void setIcon(Drawable icon) {
206         getMixin(IconMixin.class).setIcon(icon);
207     }
208 
getIcon()209     public Drawable getIcon() {
210         return getMixin(IconMixin.class).getIcon();
211     }
212 
213     /**
214      * Sets the primary color of this layout, which will be used to determine the color of the
215      * progress bar and the background pattern.
216      */
setPrimaryColor(@onNull ColorStateList color)217     public void setPrimaryColor(@NonNull ColorStateList color) {
218         mPrimaryColor = color;
219         updateBackground();
220         getMixin(ProgressBarMixin.class).setColor(color);
221     }
222 
getPrimaryColor()223     public ColorStateList getPrimaryColor() {
224         return mPrimaryColor;
225     }
226 
227     /**
228      * Sets the base color of the background view, which is the status bar for phones and the full-
229      * screen background for tablets. If {@link #isBackgroundPatterned()} is true, the pattern will
230      * be drawn with this color.
231      *
232      * @param color The color to use as the base color of the background. If {@code null},
233      *              {@link #getPrimaryColor()} will be used.
234      */
setBackgroundBaseColor(@ullable ColorStateList color)235     public void setBackgroundBaseColor(@Nullable ColorStateList color) {
236         mBackgroundBaseColor = color;
237         updateBackground();
238     }
239 
240     /**
241      * @return The base color of the background. {@code null} indicates the background will be drawn
242      *         with {@link #getPrimaryColor()}.
243      */
244     @Nullable
getBackgroundBaseColor()245     public ColorStateList getBackgroundBaseColor() {
246         return mBackgroundBaseColor;
247     }
248 
249     /**
250      * Sets whether the background should be {@link GlifPatternDrawable}. If {@code false}, the
251      * background will be a solid color.
252      */
setBackgroundPatterned(boolean patterned)253     public void setBackgroundPatterned(boolean patterned) {
254         mBackgroundPatterned = patterned;
255         updateBackground();
256     }
257 
258     /**
259      * @return True if this view uses {@link GlifPatternDrawable} as background.
260      */
isBackgroundPatterned()261     public boolean isBackgroundPatterned() {
262         return mBackgroundPatterned;
263     }
264 
updateBackground()265     private void updateBackground() {
266         final View patternBg = findManagedViewById(R.id.suw_pattern_bg);
267         if (patternBg != null) {
268             int backgroundColor = 0;
269             if (mBackgroundBaseColor != null) {
270                 backgroundColor = mBackgroundBaseColor.getDefaultColor();
271             } else if (mPrimaryColor != null) {
272                 backgroundColor = mPrimaryColor.getDefaultColor();
273             }
274             Drawable background = mBackgroundPatterned
275                     ? new GlifPatternDrawable(backgroundColor)
276                     : new ColorDrawable(backgroundColor);
277             if (patternBg instanceof StatusBarBackgroundLayout) {
278                 ((StatusBarBackgroundLayout) patternBg).setStatusBarBackground(background);
279             } else {
280                 patternBg.setBackgroundDrawable(background);
281             }
282         }
283         if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
284             setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
285         }
286     }
287 
isProgressBarShown()288     public boolean isProgressBarShown() {
289         return getMixin(ProgressBarMixin.class).isShown();
290     }
291 
setProgressBarShown(boolean shown)292     public void setProgressBarShown(boolean shown) {
293         getMixin(ProgressBarMixin.class).setShown(shown);
294     }
295 
peekProgressBar()296     public ProgressBar peekProgressBar() {
297         return getMixin(ProgressBarMixin.class).peekProgressBar();
298     }
299 }
300