• 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 android.content.Context;
20 import android.graphics.drawable.Drawable;
21 import android.view.LayoutInflater;
22 import android.view.ViewGroup;
23 import android.widget.FrameLayout;
24 
25 import androidx.annotation.DrawableRes;
26 import androidx.annotation.NonNull;
27 import androidx.annotation.Nullable;
28 import androidx.annotation.StringRes;
29 import androidx.preference.Preference;
30 
31 import com.android.car.settings.R;
32 import com.android.car.ui.uxr.DrawableStateToggleButton;
33 
34 import java.util.function.Consumer;
35 
36 /**
37  * Handles ToggleButton action item logic
38  */
39 public final class ToggleButtonActionItem extends BaseActionItem {
40     private boolean mIsChecked = true;
41     @Nullable
42     private Consumer<Boolean> mOnClickListener;
43     @Nullable
44     private Consumer<Preference> mOnClickWhileDisabledListener;
45 
46     @Nullable
47     private Drawable mDrawable;
48 
49     @Nullable
50     private String mContentDescription;
51 
ToggleButtonActionItem(ActionItemInfoChangeListener actionItemInfoChangeListener)52     public ToggleButtonActionItem(ActionItemInfoChangeListener actionItemInfoChangeListener) {
53         super(actionItemInfoChangeListener);
54     }
55 
56     /**
57      * Create and setup views.
58      *
59      * @param frameLayout ViewGroup to attach views to
60      */
61     @Override
bindViewHolder(FrameLayout frameLayout)62     public void bindViewHolder(FrameLayout frameLayout) {
63         // Required to be effectively final for inner class access
64         final DrawableStateToggleButton toggleButton = getOptionalToggleButton(frameLayout);
65         toggleButton.setOnClickListener(null);
66         // Prevent "double calls" when checked status is changed
67         toggleButton.setOnCheckedChangeListener(null);
68         toggleButton.setButtonDrawable(mDrawable);
69         toggleButton.setChecked(mIsChecked);
70         toggleButton.setEnabled(isEnabled());
71         toggleButton.setAllowClickWhenDisabled(true);
72         toggleButton.setContentDescription(mContentDescription);
73         toggleButton.setOnCheckedChangeListener((view, isChecked) -> {
74             onClick();
75             toggleButton.setChecked(mIsChecked);
76         });
77     }
78 
getOptionalToggleButton(FrameLayout frameLayout)79     private DrawableStateToggleButton getOptionalToggleButton(FrameLayout frameLayout) {
80         DrawableStateToggleButton toggleButton =
81                 frameLayout.findViewById(R.id.multi_action_preference_toggle_button);
82 
83         if (toggleButton == null) {
84             toggleButton = createView(frameLayout.getContext(), frameLayout);
85             // Ensure the default "On" and "Off" text don't show
86             toggleButton.setText(null);
87             toggleButton.setTextOn(null);
88             toggleButton.setTextOff(null);
89             frameLayout.addView(toggleButton);
90         }
91         return toggleButton;
92     }
93 
94     @Override
getLayoutResource()95     public int getLayoutResource() {
96         return R.layout.multi_action_preference_toggle_button;
97     }
98 
99     /**
100      * Set the checked state.
101      */
isChecked()102     public boolean isChecked() {
103         return mIsChecked;
104     }
105 
106     /**
107      * Get the checked state.
108      */
setChecked(boolean checked)109     public void setChecked(boolean checked) {
110         if (checked != mIsChecked) {
111             mIsChecked = checked;
112             update();
113         }
114     }
115 
116     /**
117      * Get the Consumer that should run when toggle button is clicked.
118      */
getOnClickListener()119     public Consumer<Boolean> getOnClickListener() {
120         return mOnClickListener;
121     }
122 
123     /**
124      * Set the Consumer that should run when toggle button is clicked.
125      */
setOnClickListener(Consumer<Boolean> onClickListener)126     public void setOnClickListener(Consumer<Boolean> onClickListener) {
127         if (onClickListener != mOnClickListener) {
128             mOnClickListener = onClickListener;
129             update();
130         }
131     }
132 
133     /**
134      * Set the Consumer that should run when toggle button is clicked even when disabled.
135      */
setOnClickWhileDisabledListener(Consumer<Preference> listener)136     public void setOnClickWhileDisabledListener(Consumer<Preference> listener) {
137         if (listener != mOnClickWhileDisabledListener) {
138             mOnClickWhileDisabledListener = listener;
139             update();
140         }
141     }
142 
143     /**
144      * Get the ToggleButton drawable.
145      */
getDrawable()146     public Drawable getDrawable() {
147         return mDrawable;
148     }
149 
150     /**
151      * Set the ToggleButton drawable.
152      */
setDrawable(Drawable drawable)153     public void setDrawable(Drawable drawable) {
154         if (drawable != mDrawable) {
155             mDrawable = drawable;
156             update();
157         }
158     }
159 
160     /**
161      * Set the ToggleButton drawable.
162      */
setDrawable(Context context, @DrawableRes int iconResId)163     public void setDrawable(Context context, @DrawableRes int iconResId) {
164         Drawable drawable = context.getDrawable(iconResId);
165 
166         if (drawable != mDrawable) {
167             mDrawable = drawable;
168             update();
169         }
170     }
171 
172     /**
173      * Get the ToggleButton content description.
174      */
175     @Nullable
getContentDescription()176     public String getContentDescription() {
177         return mContentDescription;
178     }
179 
180     /**
181      * Set the ToggleButton content description.
182      */
setContentDescription(@ullable String contentDescription)183     public void setContentDescription(@Nullable String contentDescription) {
184         mContentDescription = contentDescription;
185     }
186 
187     /**
188      * Set the ToggleButton content description.
189      */
setContentDescription(@onNull Context context, @StringRes int contentDescriptionResId)190     public void setContentDescription(@NonNull Context context,
191             @StringRes int contentDescriptionResId) {
192         mContentDescription = context.getString(contentDescriptionResId);
193     }
194 
195     /**
196      * Executes when ToggleButton is clicked.
197      */
onClick()198     public void onClick() {
199         if (mIsRestricted && mPreference != null
200                 && mRestrictedOnClickListener != null) {
201             mRestrictedOnClickListener.accept(mPreference);
202         } else if (isEnabled() && !mIsRestricted && mOnClickListener != null) {
203             mIsChecked = !mIsChecked;
204             mOnClickListener.accept(mIsChecked);
205         } else if (!isEnabled() && mOnClickWhileDisabledListener != null) {
206             mOnClickWhileDisabledListener.accept(mPreference);
207         }
208     }
209 
createView(Context context, ViewGroup viewGroup)210     private DrawableStateToggleButton createView(Context context, ViewGroup viewGroup) {
211         LayoutInflater layoutInflater = LayoutInflater.from(context);
212 
213         return (DrawableStateToggleButton) layoutInflater
214                 .inflate(getLayoutResource(), viewGroup, false);
215     }
216 }
217