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 17package com.android.setupwizardlib.items; 18 19import android.content.Context; 20import android.content.res.ColorStateList; 21import android.content.res.TypedArray; 22import android.graphics.PorterDuff.Mode; 23import android.graphics.drawable.Drawable; 24import android.os.Build.VERSION; 25import android.os.Build.VERSION_CODES; 26import android.util.AttributeSet; 27import android.view.View; 28import android.view.View.OnClickListener; 29import android.widget.CompoundButton.OnCheckedChangeListener; 30import android.widget.TextView; 31 32import com.android.setupwizardlib.R; 33import com.android.setupwizardlib.view.CheckableLinearLayout; 34 35/** 36 * A switch item which is divided into two parts: the start (left for LTR) side shows the title and 37 * summary, and when that is clicked, will expand to show a longer summary. The end (right for LTR) 38 * side is a switch which can be toggled by the user. 39 * 40 * Note: It is highly recommended to use this item with recycler view rather than list view, because 41 * list view draws the touch ripple effect on top of the item, rather than letting the item handle 42 * it. Therefore you might see a double-ripple, one for the expandable area and one for the entire 43 * list item, when using this in list view. 44 */ 45public class ExpandableSwitchItem extends SwitchItem 46 implements OnCheckedChangeListener, OnClickListener { 47 48 private CharSequence mCollapsedSummary; 49 private CharSequence mExpandedSummary; 50 private boolean mIsExpanded = false; 51 52 public ExpandableSwitchItem() { 53 super(); 54 } 55 56 public ExpandableSwitchItem(Context context, AttributeSet attrs) { 57 super(context, attrs); 58 final TypedArray a = 59 context.obtainStyledAttributes(attrs, R.styleable.SuwExpandableSwitchItem); 60 mCollapsedSummary = a.getText(R.styleable.SuwExpandableSwitchItem_suwCollapsedSummary); 61 mExpandedSummary = a.getText(R.styleable.SuwExpandableSwitchItem_suwExpandedSummary); 62 a.recycle(); 63 } 64 65 @Override 66 protected int getDefaultLayoutResource() { 67 return R.layout.suw_items_expandable_switch; 68 } 69 70 @Override 71 public CharSequence getSummary() { 72 return mIsExpanded ? getExpandedSummary() : getCollapsedSummary(); 73 } 74 75 /** 76 * @return True if the item is currently expanded. 77 */ 78 public boolean isExpanded() { 79 return mIsExpanded; 80 } 81 82 /** 83 * Sets whether the item should be expanded. 84 */ 85 public void setExpanded(boolean expanded) { 86 if (mIsExpanded == expanded) { 87 return; 88 } 89 mIsExpanded = expanded; 90 notifyItemChanged(); 91 } 92 93 /** 94 * @return The summary shown when in collapsed state. 95 */ 96 public CharSequence getCollapsedSummary() { 97 return mCollapsedSummary; 98 } 99 100 /** 101 * Sets the summary text shown when the item is collapsed. Corresponds to the 102 * {@code app:suwCollapsedSummary} XML attribute. 103 */ 104 public void setCollapsedSummary(CharSequence collapsedSummary) { 105 mCollapsedSummary = collapsedSummary; 106 if (!isExpanded()) { 107 notifyChanged(); 108 } 109 } 110 111 /** 112 * @return The summary shown when in expanded state. 113 */ 114 public CharSequence getExpandedSummary() { 115 return mExpandedSummary; 116 } 117 118 /** 119 * Sets the summary text shown when the item is expanded. Corresponds to the 120 * {@code app:suwExpandedSummary} XML attribute. 121 */ 122 public void setExpandedSummary(CharSequence expandedSummary) { 123 mExpandedSummary = expandedSummary; 124 if (isExpanded()) { 125 notifyChanged(); 126 } 127 } 128 129 @Override 130 public void onBindView(View view) { 131 // TODO: If it is possible to detect, log a warning if this is being used with ListView. 132 super.onBindView(view); 133 View content = view.findViewById(R.id.suw_items_expandable_switch_content); 134 content.setOnClickListener(this); 135 136 if (content instanceof CheckableLinearLayout) { 137 ((CheckableLinearLayout) content).setChecked(isExpanded()); 138 } 139 140 tintCompoundDrawables(view); 141 142 // Expandable switch item has focusability on the expandable layout on the left, and the 143 // switch on the right, but not the item itself. 144 view.setFocusable(false); 145 } 146 147 @Override 148 public void onClick(View v) { 149 setExpanded(!isExpanded()); 150 } 151 152 // Tint the expand arrow with the text color 153 private void tintCompoundDrawables(View view) { 154 final TypedArray a = view.getContext() 155 .obtainStyledAttributes(new int[] {android.R.attr.textColorPrimary}); 156 final ColorStateList tintColor = a.getColorStateList(0); 157 a.recycle(); 158 159 if (tintColor != null) { 160 TextView titleView = (TextView) view.findViewById(R.id.suw_items_title); 161 for (Drawable drawable : titleView.getCompoundDrawables()) { 162 if (drawable != null) { 163 drawable.setColorFilter(tintColor.getDefaultColor(), Mode.SRC_IN); 164 } 165 } 166 if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR1) { 167 for (Drawable drawable : titleView.getCompoundDrawablesRelative()) { 168 if (drawable != null) { 169 drawable.setColorFilter(tintColor.getDefaultColor(), Mode.SRC_IN); 170 } 171 } 172 } 173 174 } 175 } 176} 177