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