• 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.google.android.setupdesign.items;
18 
19 import android.content.Context;
20 import android.content.res.TypedArray;
21 import android.graphics.Color;
22 import android.graphics.drawable.Drawable;
23 import android.util.AttributeSet;
24 import android.view.Gravity;
25 import android.view.View;
26 import android.view.ViewGroup.LayoutParams;
27 import android.widget.ImageView;
28 import android.widget.LinearLayout;
29 import android.widget.TextView;
30 import androidx.annotation.ColorInt;
31 import androidx.annotation.Nullable;
32 import com.google.android.setupdesign.R;
33 import com.google.android.setupdesign.util.ItemStyler;
34 import com.google.android.setupdesign.util.LayoutStyler;
35 
36 /**
37  * Definition of an item in an {@link ItemHierarchy}. An item is usually defined in XML and inflated
38  * using {@link ItemInflater}.
39  */
40 public class Item extends AbstractItem {
41 
42   private boolean enabled = true;
43   @Nullable private Drawable icon;
44   private int layoutRes;
45   @Nullable private CharSequence summary;
46   @Nullable private CharSequence title;
47   @Nullable private CharSequence contentDescription;
48   private boolean visible = true;
49   @ColorInt private int iconTint = Color.TRANSPARENT;
50   private int iconGravity = Gravity.CENTER_VERTICAL;
51 
Item()52   public Item() {
53     super();
54     layoutRes = getDefaultLayoutResource();
55   }
56 
Item(Context context, AttributeSet attrs)57   public Item(Context context, AttributeSet attrs) {
58     super(context, attrs);
59     TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SudItem);
60     enabled = a.getBoolean(R.styleable.SudItem_android_enabled, true);
61     icon = a.getDrawable(R.styleable.SudItem_android_icon);
62     title = a.getText(R.styleable.SudItem_android_title);
63     summary = a.getText(R.styleable.SudItem_android_summary);
64     contentDescription = a.getText(R.styleable.SudItem_android_contentDescription);
65     layoutRes = a.getResourceId(R.styleable.SudItem_android_layout, getDefaultLayoutResource());
66     visible = a.getBoolean(R.styleable.SudItem_android_visible, true);
67     iconTint = a.getColor(R.styleable.SudItem_sudIconTint, Color.TRANSPARENT);
68     iconGravity = a.getInt(R.styleable.SudItem_sudIconGravity, Gravity.CENTER_VERTICAL);
69 
70     a.recycle();
71   }
72 
getDefaultLayoutResource()73   protected int getDefaultLayoutResource() {
74     return R.layout.sud_items_default;
75   }
76 
setEnabled(boolean enabled)77   public void setEnabled(boolean enabled) {
78     this.enabled = enabled;
79     notifyItemChanged();
80   }
81 
82   @Override
getCount()83   public int getCount() {
84     return isVisible() ? 1 : 0;
85   }
86 
87   @Override
isEnabled()88   public boolean isEnabled() {
89     return enabled;
90   }
91 
setIcon(@ullable Drawable icon)92   public void setIcon(@Nullable Drawable icon) {
93     this.icon = icon;
94     notifyItemChanged();
95   }
96 
97   @Nullable
getIcon()98   public Drawable getIcon() {
99     return icon;
100   }
101 
setIconTint(@olorInt int iconTint)102   public void setIconTint(@ColorInt int iconTint) {
103     this.iconTint = iconTint;
104   }
105 
106   @ColorInt
getIconTint()107   public int getIconTint() {
108     return iconTint;
109   }
110 
setIconGravity(int iconGravity)111   public void setIconGravity(int iconGravity) {
112     this.iconGravity = iconGravity;
113   }
114 
getIconGravity()115   public int getIconGravity() {
116     return iconGravity;
117   }
118 
setLayoutResource(int layoutResource)119   public void setLayoutResource(int layoutResource) {
120     layoutRes = layoutResource;
121     notifyItemChanged();
122   }
123 
124   @Override
getLayoutResource()125   public int getLayoutResource() {
126     return layoutRes;
127   }
128 
setSummary(@ullable CharSequence summary)129   public void setSummary(@Nullable CharSequence summary) {
130     this.summary = summary;
131     notifyItemChanged();
132   }
133 
134   @Nullable
getSummary()135   public CharSequence getSummary() {
136     return summary;
137   }
138 
setTitle(@ullable CharSequence title)139   public void setTitle(@Nullable CharSequence title) {
140     this.title = title;
141     notifyItemChanged();
142   }
143 
144   @Nullable
getTitle()145   public CharSequence getTitle() {
146     return title;
147   }
148 
149   @Nullable
getContentDescription()150   public CharSequence getContentDescription() {
151     return contentDescription;
152   }
153 
setContentDescription(@ullable CharSequence contentDescription)154   public void setContentDescription(@Nullable CharSequence contentDescription) {
155     this.contentDescription = contentDescription;
156     notifyItemChanged();
157   }
158 
setVisible(boolean visible)159   public void setVisible(boolean visible) {
160     if (this.visible == visible) {
161       return;
162     }
163     this.visible = visible;
164     if (!visible) {
165       notifyItemRangeRemoved(0, 1);
166     } else {
167       notifyItemRangeInserted(0, 1);
168     }
169   }
170 
isVisible()171   public boolean isVisible() {
172     return visible;
173   }
174 
hasSummary(CharSequence summary)175   private boolean hasSummary(CharSequence summary) {
176     return summary != null && summary.length() > 0;
177   }
178 
179   @Override
getViewId()180   public int getViewId() {
181     return getId();
182   }
183 
184   @Override
onBindView(View view)185   public void onBindView(View view) {
186     TextView label = (TextView) view.findViewById(R.id.sud_items_title);
187     label.setText(getTitle());
188 
189     TextView summaryView = (TextView) view.findViewById(R.id.sud_items_summary);
190     CharSequence summary = getSummary();
191     if (hasSummary(summary)) {
192       summaryView.setText(summary);
193       summaryView.setVisibility(View.VISIBLE);
194     } else {
195       summaryView.setVisibility(View.GONE);
196     }
197 
198     view.setContentDescription(getContentDescription());
199 
200     final View iconContainer = view.findViewById(R.id.sud_items_icon_container);
201     final Drawable icon = getIcon();
202     if (icon != null) {
203       final ImageView iconView = (ImageView) view.findViewById(R.id.sud_items_icon);
204       // Set the image drawable to null before setting the state and level to avoid affecting
205       // any recycled drawable in the ImageView
206       iconView.setImageDrawable(null);
207       onMergeIconStateAndLevels(iconView, icon);
208       iconView.setImageDrawable(icon);
209       if (iconTint != Color.TRANSPARENT) {
210         iconView.setColorFilter(iconTint);
211       } else {
212         iconView.clearColorFilter();
213       }
214       LayoutParams layoutParams = iconContainer.getLayoutParams();
215       if (layoutParams instanceof LinearLayout.LayoutParams) {
216         ((LinearLayout.LayoutParams) layoutParams).gravity = iconGravity;
217       }
218       iconContainer.setVisibility(View.VISIBLE);
219     } else {
220       iconContainer.setVisibility(View.GONE);
221     }
222 
223     view.setId(getViewId());
224 
225     // ExpandableSwitchItem uses its child view to apply the style SudItemContainer. It is not
226     // possible to directly adjust the padding start/end of the item's layout here. It needs to
227     // get its child view to adjust it first, so skip the Layout padding adjustment.
228     // If the item view is a header layout, it doesn't need to adjust the layout padding start/end
229     // here. It will be adjusted by HeaderMixin.
230     // TODO: Add partner resource enable check
231     if (!(this instanceof ExpandableSwitchItem) && view.getId() != R.id.sud_layout_header) {
232       LayoutStyler.applyPartnerCustomizationLayoutPaddingStyle(view);
233     }
234     ItemStyler.applyPartnerCustomizationItemStyle(view);
235   }
236 
237   /**
238    * Copies state and level information from {@link #getIcon()} to the currently bound view's
239    * ImageView. Subclasses can override this method to change whats being copied from the icon to
240    * the ImageView.
241    */
onMergeIconStateAndLevels(ImageView iconView, Drawable icon)242   protected void onMergeIconStateAndLevels(ImageView iconView, Drawable icon) {
243     iconView.setImageState(icon.getState(), false /* merge */);
244     iconView.setImageLevel(icon.getLevel());
245   }
246 }
247