1 /* 2 * Copyright (C) 2021 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.car.settings.common; 18 19 import static com.android.car.ui.utils.CarUiUtils.requireViewByRefId; 20 21 import android.content.Context; 22 import android.content.res.TypedArray; 23 import android.util.AttributeSet; 24 import android.view.View; 25 import android.widget.FrameLayout; 26 27 import androidx.annotation.CallSuper; 28 import androidx.annotation.Nullable; 29 import androidx.preference.PreferenceViewHolder; 30 31 import com.android.car.settings.R; 32 import com.android.car.ui.preference.CarUiPreference; 33 34 /** 35 * A class for preferences that have a main click action along with up to three other actions. 36 */ 37 public class MultiActionPreference extends CarUiPreference 38 implements BaseActionItem.ActionItemInfoChangeListener { 39 40 /** 41 * Identifier enum for the three different action items. 42 */ 43 public enum ActionItem { 44 ACTION_ITEM1, 45 ACTION_ITEM2, 46 ACTION_ITEM3, 47 } 48 49 protected BaseActionItem[] mActionItemArray = new BaseActionItem[3]; 50 MultiActionPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)51 public MultiActionPreference(Context context, 52 AttributeSet attrs, 53 int defStyleAttr, int defStyleRes) { 54 super(context, attrs, defStyleAttr, defStyleRes); 55 init(attrs); 56 } 57 MultiActionPreference(Context context, AttributeSet attrs, int defStyleAttr)58 public MultiActionPreference(Context context, AttributeSet attrs, int defStyleAttr) { 59 super(context, attrs, defStyleAttr); 60 init(attrs); 61 } 62 MultiActionPreference(Context context, AttributeSet attrs)63 public MultiActionPreference(Context context, AttributeSet attrs) { 64 super(context, attrs); 65 init(attrs); 66 } 67 MultiActionPreference(Context context)68 public MultiActionPreference(Context context) { 69 super(context); 70 init(null); 71 } 72 73 /** 74 * Initialize styles and attributes, as well as what types of action items should be created. 75 * 76 * @param attrs Attribute set from which to read values 77 */ 78 @CallSuper init(@ullable AttributeSet attrs)79 protected void init(@Nullable AttributeSet attrs) { 80 TypedArray a = getContext().obtainStyledAttributes(attrs, 81 R.styleable.MultiActionPreference); 82 83 try { 84 // Single case switch statement for now with the assumption more ActionItems will be 85 // added in the future 86 switch(a.getInt( 87 R.styleable.MultiActionPreference_action_item_one, -1)) { 88 case 0: 89 mActionItemArray[0] = new ToggleButtonActionItem(this); 90 break; 91 default: 92 break; 93 } 94 95 switch(a.getInt( 96 R.styleable.MultiActionPreference_action_item_two, -1)) { 97 case 0: 98 mActionItemArray[1] = new ToggleButtonActionItem(this); 99 break; 100 default: 101 break; 102 } 103 104 switch(a.getInt( 105 R.styleable.MultiActionPreference_action_item_three, -1)) { 106 case 0: 107 mActionItemArray[2] = new ToggleButtonActionItem(this); 108 break; 109 default: 110 break; 111 } 112 113 int[] actionItemVisibility = { 114 R.styleable.MultiActionPreference_action_item_one_shown, 115 R.styleable.MultiActionPreference_action_item_two_shown, 116 R.styleable.MultiActionPreference_action_item_three_shown}; 117 int[] actionItemEnabled = { 118 R.styleable.MultiActionPreference_action_item_one_enabled, 119 R.styleable.MultiActionPreference_action_item_two_enabled, 120 R.styleable.MultiActionPreference_action_item_three_enabled}; 121 122 for (int i = 0; i < mActionItemArray.length; i++) { 123 if (mActionItemArray[i] != null) { 124 mActionItemArray[i].setVisible(a.getBoolean( 125 actionItemVisibility[i], true)); 126 mActionItemArray[i].setEnabled(a.getBoolean( 127 actionItemEnabled[i], true)); 128 } 129 } 130 } finally { 131 a.recycle(); 132 } 133 134 setLayoutResource(R.layout.multi_action_preference); 135 } 136 137 @Override onBindViewHolder(PreferenceViewHolder holder)138 public void onBindViewHolder(PreferenceViewHolder holder) { 139 super.onBindViewHolder(holder); 140 View actionContainer = requireViewByRefId(holder.itemView, 141 R.id.multi_action_preference_second_action_container); 142 FrameLayout container1 = requireViewByRefId(holder.itemView, 143 R.id.multi_action_preference_item_container1); 144 FrameLayout container2 = requireViewByRefId(holder.itemView, 145 R.id.multi_action_preference_item_container2); 146 FrameLayout container3 = requireViewByRefId(holder.itemView, 147 R.id.multi_action_preference_item_container3); 148 149 boolean isActionContainerVisible = false; 150 for (BaseActionItem baseActionItem: mActionItemArray) { 151 if (baseActionItem != null) { 152 baseActionItem.setPreference(this) 153 .setRestrictedOnClickListener(getOnClickWhileRestrictedListener()); 154 155 if (baseActionItem.isVisible()) { 156 isActionContainerVisible = true; 157 } 158 } 159 } 160 161 actionContainer.setVisibility(isActionContainerVisible ? View.VISIBLE : View.GONE); 162 163 if (mActionItemArray[0] != null) { 164 mActionItemArray[0].bindViewHolder(container1); 165 } 166 167 if (mActionItemArray[1] != null) { 168 mActionItemArray[1].bindViewHolder(container2); 169 } 170 171 if (mActionItemArray[2] != null) { 172 mActionItemArray[2].bindViewHolder(container3); 173 } 174 } 175 176 @Override onActionItemChange(BaseActionItem baseActionItem)177 public void onActionItemChange(BaseActionItem baseActionItem) { 178 notifyChanged(); 179 } 180 181 /** 182 * Retrieve the specified BaseActionItem based on the index. 183 */ getActionItem(ActionItem actionItem)184 public BaseActionItem getActionItem(ActionItem actionItem) { 185 switch (actionItem) { 186 case ACTION_ITEM1: 187 return mActionItemArray[0]; 188 case ACTION_ITEM2: 189 return mActionItemArray[1]; 190 case ACTION_ITEM3: 191 return mActionItemArray[2]; 192 default: 193 throw new IllegalArgumentException("Invalid button requested"); 194 } 195 } 196 } 197