• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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