| /* |
| * Copyright (C) 2015 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.google.android.setupdesign.items; |
| |
| import android.content.Context; |
| import android.content.res.TypedArray; |
| import android.graphics.Color; |
| import android.graphics.drawable.Drawable; |
| import android.util.AttributeSet; |
| import android.view.Gravity; |
| import android.view.View; |
| import android.view.ViewGroup.LayoutParams; |
| import android.widget.ImageView; |
| import android.widget.LinearLayout; |
| import android.widget.TextView; |
| import androidx.annotation.ColorInt; |
| import androidx.annotation.Nullable; |
| import com.google.android.setupdesign.R; |
| import com.google.android.setupdesign.util.ItemStyler; |
| import com.google.android.setupdesign.util.LayoutStyler; |
| |
| /** |
| * Definition of an item in an {@link ItemHierarchy}. An item is usually defined in XML and inflated |
| * using {@link ItemInflater}. |
| */ |
| public class Item extends AbstractItem { |
| |
| private boolean enabled = true; |
| @Nullable private Drawable icon; |
| private int layoutRes; |
| @Nullable private CharSequence summary; |
| @Nullable private CharSequence title; |
| @Nullable private CharSequence contentDescription; |
| private boolean visible = true; |
| @ColorInt private int iconTint = Color.TRANSPARENT; |
| private int iconGravity = Gravity.CENTER_VERTICAL; |
| |
| public Item() { |
| super(); |
| layoutRes = getDefaultLayoutResource(); |
| } |
| |
| public Item(Context context, AttributeSet attrs) { |
| super(context, attrs); |
| TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SudItem); |
| enabled = a.getBoolean(R.styleable.SudItem_android_enabled, true); |
| icon = a.getDrawable(R.styleable.SudItem_android_icon); |
| title = a.getText(R.styleable.SudItem_android_title); |
| summary = a.getText(R.styleable.SudItem_android_summary); |
| contentDescription = a.getText(R.styleable.SudItem_android_contentDescription); |
| layoutRes = a.getResourceId(R.styleable.SudItem_android_layout, getDefaultLayoutResource()); |
| visible = a.getBoolean(R.styleable.SudItem_android_visible, true); |
| iconTint = a.getColor(R.styleable.SudItem_sudIconTint, Color.TRANSPARENT); |
| iconGravity = a.getInt(R.styleable.SudItem_sudIconGravity, Gravity.CENTER_VERTICAL); |
| |
| a.recycle(); |
| } |
| |
| protected int getDefaultLayoutResource() { |
| return R.layout.sud_items_default; |
| } |
| |
| public void setEnabled(boolean enabled) { |
| this.enabled = enabled; |
| notifyItemChanged(); |
| } |
| |
| @Override |
| public int getCount() { |
| return isVisible() ? 1 : 0; |
| } |
| |
| @Override |
| public boolean isEnabled() { |
| return enabled; |
| } |
| |
| public void setIcon(@Nullable Drawable icon) { |
| this.icon = icon; |
| notifyItemChanged(); |
| } |
| |
| @Nullable |
| public Drawable getIcon() { |
| return icon; |
| } |
| |
| public void setIconTint(@ColorInt int iconTint) { |
| this.iconTint = iconTint; |
| } |
| |
| @ColorInt |
| public int getIconTint() { |
| return iconTint; |
| } |
| |
| public void setIconGravity(int iconGravity) { |
| this.iconGravity = iconGravity; |
| } |
| |
| public int getIconGravity() { |
| return iconGravity; |
| } |
| |
| public void setLayoutResource(int layoutResource) { |
| layoutRes = layoutResource; |
| notifyItemChanged(); |
| } |
| |
| @Override |
| public int getLayoutResource() { |
| return layoutRes; |
| } |
| |
| public void setSummary(@Nullable CharSequence summary) { |
| this.summary = summary; |
| notifyItemChanged(); |
| } |
| |
| @Nullable |
| public CharSequence getSummary() { |
| return summary; |
| } |
| |
| public void setTitle(@Nullable CharSequence title) { |
| this.title = title; |
| notifyItemChanged(); |
| } |
| |
| @Nullable |
| public CharSequence getTitle() { |
| return title; |
| } |
| |
| @Nullable |
| public CharSequence getContentDescription() { |
| return contentDescription; |
| } |
| |
| public void setContentDescription(@Nullable CharSequence contentDescription) { |
| this.contentDescription = contentDescription; |
| notifyItemChanged(); |
| } |
| |
| public void setVisible(boolean visible) { |
| if (this.visible == visible) { |
| return; |
| } |
| this.visible = visible; |
| if (!visible) { |
| notifyItemRangeRemoved(0, 1); |
| } else { |
| notifyItemRangeInserted(0, 1); |
| } |
| } |
| |
| public boolean isVisible() { |
| return visible; |
| } |
| |
| private boolean hasSummary(CharSequence summary) { |
| return summary != null && summary.length() > 0; |
| } |
| |
| @Override |
| public int getViewId() { |
| return getId(); |
| } |
| |
| @Override |
| public void onBindView(View view) { |
| TextView label = (TextView) view.findViewById(R.id.sud_items_title); |
| label.setText(getTitle()); |
| |
| TextView summaryView = (TextView) view.findViewById(R.id.sud_items_summary); |
| CharSequence summary = getSummary(); |
| if (hasSummary(summary)) { |
| summaryView.setText(summary); |
| summaryView.setVisibility(View.VISIBLE); |
| } else { |
| summaryView.setVisibility(View.GONE); |
| } |
| |
| view.setContentDescription(getContentDescription()); |
| |
| final View iconContainer = view.findViewById(R.id.sud_items_icon_container); |
| final Drawable icon = getIcon(); |
| if (icon != null) { |
| final ImageView iconView = (ImageView) view.findViewById(R.id.sud_items_icon); |
| // Set the image drawable to null before setting the state and level to avoid affecting |
| // any recycled drawable in the ImageView |
| iconView.setImageDrawable(null); |
| onMergeIconStateAndLevels(iconView, icon); |
| iconView.setImageDrawable(icon); |
| if (iconTint != Color.TRANSPARENT) { |
| iconView.setColorFilter(iconTint); |
| } else { |
| iconView.clearColorFilter(); |
| } |
| LayoutParams layoutParams = iconContainer.getLayoutParams(); |
| if (layoutParams instanceof LinearLayout.LayoutParams) { |
| ((LinearLayout.LayoutParams) layoutParams).gravity = iconGravity; |
| } |
| iconContainer.setVisibility(View.VISIBLE); |
| } else { |
| iconContainer.setVisibility(View.GONE); |
| } |
| |
| view.setId(getViewId()); |
| |
| // ExpandableSwitchItem uses its child view to apply the style SudItemContainer. It is not |
| // possible to directly adjust the padding start/end of the item's layout here. It needs to |
| // get its child view to adjust it first, so skip the Layout padding adjustment. |
| // If the item view is a header layout, it doesn't need to adjust the layout padding start/end |
| // here. It will be adjusted by HeaderMixin. |
| // TODO: Add partner resource enable check |
| if (!(this instanceof ExpandableSwitchItem) && view.getId() != R.id.sud_layout_header) { |
| LayoutStyler.applyPartnerCustomizationLayoutPaddingStyle(view); |
| } |
| ItemStyler.applyPartnerCustomizationItemStyle(view); |
| } |
| |
| /** |
| * Copies state and level information from {@link #getIcon()} to the currently bound view's |
| * ImageView. Subclasses can override this method to change whats being copied from the icon to |
| * the ImageView. |
| */ |
| protected void onMergeIconStateAndLevels(ImageView iconView, Drawable icon) { |
| iconView.setImageState(icon.getState(), false /* merge */); |
| iconView.setImageLevel(icon.getLevel()); |
| } |
| } |