1 /* 2 * Copyright (C) 2020 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.ui.preference; 18 19 import static com.android.car.ui.core.CarUi.MIN_TARGET_API; 20 import static com.android.car.ui.utils.CarUiUtils.requireViewByRefId; 21 22 import android.annotation.TargetApi; 23 import android.content.Context; 24 import android.util.AttributeSet; 25 import android.view.View; 26 import android.widget.Switch; 27 28 import androidx.annotation.Nullable; 29 import androidx.preference.PreferenceViewHolder; 30 31 import com.android.car.ui.R; 32 import com.android.car.ui.utils.CarUiUtils; 33 34 import java.util.function.Consumer; 35 36 /** 37 * A preference that has a switch that can be toggled independently of pressing the main 38 * body of the preference. 39 */ 40 @SuppressWarnings("AndroidJdkLibsChecker") 41 @TargetApi(MIN_TARGET_API) 42 public class CarUiTwoActionSwitchPreference extends CarUiTwoActionBasePreference { 43 @Nullable 44 protected Consumer<Boolean> mSecondaryActionOnClickListener; 45 private boolean mSecondaryActionChecked; 46 CarUiTwoActionSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)47 public CarUiTwoActionSwitchPreference(Context context, 48 AttributeSet attrs, 49 int defStyleAttr, int defStyleRes) { 50 super(context, attrs, defStyleAttr, defStyleRes); 51 } 52 CarUiTwoActionSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr)53 public CarUiTwoActionSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) { 54 super(context, attrs, defStyleAttr); 55 } 56 CarUiTwoActionSwitchPreference(Context context, AttributeSet attrs)57 public CarUiTwoActionSwitchPreference(Context context, AttributeSet attrs) { 58 super(context, attrs); 59 } 60 CarUiTwoActionSwitchPreference(Context context)61 public CarUiTwoActionSwitchPreference(Context context) { 62 super(context); 63 } 64 65 @Override init(@ullable AttributeSet attrs)66 protected void init(@Nullable AttributeSet attrs) { 67 super.init(attrs); 68 69 setLayoutResourceInternal(R.layout.car_ui_preference_two_action_switch); 70 } 71 72 @Override performSecondaryActionClickInternal()73 protected void performSecondaryActionClickInternal() { 74 mSecondaryActionChecked = !mSecondaryActionChecked; 75 notifyChanged(); 76 if (mSecondaryActionOnClickListener != null) { 77 mSecondaryActionOnClickListener.accept(mSecondaryActionChecked); 78 } 79 } 80 81 @Override onBindViewHolder(PreferenceViewHolder holder)82 public void onBindViewHolder(PreferenceViewHolder holder) { 83 super.onBindViewHolder(holder); 84 85 View firstActionContainer = requireViewByRefId(holder.itemView, 86 R.id.car_ui_first_action_container); 87 View secondActionContainer = requireViewByRefId(holder.itemView, 88 R.id.car_ui_second_action_container); 89 View secondaryAction = requireViewByRefId(holder.itemView, 90 R.id.car_ui_secondary_action); 91 Switch s = requireViewByRefId(holder.itemView, 92 R.id.car_ui_secondary_action_concrete); 93 94 holder.itemView.setFocusable(false); 95 holder.itemView.setClickable(false); 96 firstActionContainer.setOnClickListener(this::performClickUnrestricted); 97 firstActionContainer.setEnabled( 98 isEnabled() || isUxRestricted() || isClickableWhileDisabled()); 99 firstActionContainer.setFocusable( 100 isEnabled() || isUxRestricted() || isClickableWhileDisabled()); 101 102 secondActionContainer.setVisibility(mSecondaryActionVisible ? View.VISIBLE : View.GONE); 103 s.setChecked(mSecondaryActionChecked); 104 s.setEnabled(isSecondaryActionEnabled()); 105 106 secondaryAction.setOnClickListener(v -> performSecondaryActionClick()); 107 secondaryAction.setEnabled( 108 isSecondaryActionEnabled() || isUxRestricted() || isClickableWhileDisabled()); 109 secondaryAction.setFocusable( 110 isSecondaryActionEnabled() || isUxRestricted() || isClickableWhileDisabled()); 111 112 CarUiUtils.makeAllViewsEnabledAndUxRestricted(secondaryAction, isSecondaryActionEnabled(), 113 isUxRestricted()); 114 } 115 116 /** 117 * Sets the checked state of the switch in the secondary action space. 118 * @param checked Whether the switch should be checked or not. 119 */ setSecondaryActionChecked(boolean checked)120 public void setSecondaryActionChecked(boolean checked) { 121 mSecondaryActionChecked = checked; 122 notifyChanged(); 123 } 124 125 /** 126 * Returns the checked state of the switch in the secondary action space. 127 * @return Whether the switch is checked or not. 128 */ isSecondaryActionChecked()129 public boolean isSecondaryActionChecked() { 130 return mSecondaryActionChecked; 131 } 132 133 /** 134 * Sets the on-click listener of the secondary action button. 135 * 136 * The listener is called with the current checked state of the switch. 137 */ setOnSecondaryActionClickListener(@ullable Consumer<Boolean> onClickListener)138 public void setOnSecondaryActionClickListener(@Nullable Consumer<Boolean> onClickListener) { 139 mSecondaryActionOnClickListener = onClickListener; 140 notifyChanged(); 141 } 142 } 143