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.utils.CarUiUtils.requireViewByRefId; 20 21 import android.content.Context; 22 import android.content.res.TypedArray; 23 import android.graphics.drawable.Drawable; 24 import android.util.AttributeSet; 25 import android.view.View; 26 import android.view.ViewGroup; 27 import android.widget.ImageView; 28 29 import androidx.annotation.DrawableRes; 30 import androidx.annotation.Nullable; 31 import androidx.core.content.ContextCompat; 32 import androidx.preference.Preference; 33 import androidx.preference.PreferenceViewHolder; 34 35 import com.android.car.ui.R; 36 37 import java.util.function.Consumer; 38 39 /** 40 * A preference that has an icon button that can be pressed independently of pressing the main 41 * body of the preference. 42 */ 43 @SuppressWarnings("AndroidJdkLibsChecker") 44 public class CarUiTwoActionIconPreference extends CarUiTwoActionBasePreference { 45 @Nullable 46 protected Runnable mSecondaryActionOnClickListener; 47 @Nullable 48 private Drawable mSecondaryActionIcon; 49 CarUiTwoActionIconPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)50 public CarUiTwoActionIconPreference(Context context, 51 AttributeSet attrs, 52 int defStyleAttr, int defStyleRes) { 53 super(context, attrs, defStyleAttr, defStyleRes); 54 } 55 CarUiTwoActionIconPreference(Context context, AttributeSet attrs, int defStyleAttr)56 public CarUiTwoActionIconPreference(Context context, AttributeSet attrs, int defStyleAttr) { 57 super(context, attrs, defStyleAttr); 58 } 59 CarUiTwoActionIconPreference(Context context, AttributeSet attrs)60 public CarUiTwoActionIconPreference(Context context, AttributeSet attrs) { 61 super(context, attrs); 62 } 63 CarUiTwoActionIconPreference(Context context)64 public CarUiTwoActionIconPreference(Context context) { 65 super(context); 66 } 67 68 @Override init(@ullable AttributeSet attrs)69 protected void init(@Nullable AttributeSet attrs) { 70 super.init(attrs); 71 72 TypedArray a = getContext().obtainStyledAttributes(attrs, 73 R.styleable.CarUiTwoActionIconPreference); 74 try { 75 mSecondaryActionIcon = a.getDrawable( 76 R.styleable.CarUiTwoActionIconPreference_secondaryActionIcon); 77 } finally { 78 a.recycle(); 79 } 80 81 setLayoutResourceInternal(R.layout.car_ui_preference_two_action_icon); 82 } 83 84 @Override performSecondaryActionClickInternal()85 protected void performSecondaryActionClickInternal() { 86 if (isSecondaryActionEnabled()) { 87 if (isUxRestricted()) { 88 Consumer<Preference> restrictedListener = getOnClickWhileRestrictedListener(); 89 if (restrictedListener != null) { 90 restrictedListener.accept(this); 91 } 92 } else if (mSecondaryActionOnClickListener != null) { 93 mSecondaryActionOnClickListener.run(); 94 } 95 } 96 } 97 98 @Override onBindViewHolder(PreferenceViewHolder holder)99 public void onBindViewHolder(PreferenceViewHolder holder) { 100 super.onBindViewHolder(holder); 101 102 View firstActionContainer = requireViewByRefId(holder.itemView, 103 R.id.car_ui_first_action_container); 104 View secondActionContainer = requireViewByRefId(holder.itemView, 105 R.id.car_ui_second_action_container); 106 ViewGroup secondaryButton = requireViewByRefId(holder.itemView, 107 R.id.car_ui_secondary_action); 108 ImageView iconView = requireViewByRefId(holder.itemView, 109 R.id.car_ui_secondary_action_concrete); 110 111 holder.itemView.setFocusable(false); 112 holder.itemView.setClickable(false); 113 firstActionContainer.setOnClickListener(this::performClickUnrestricted); 114 firstActionContainer.setEnabled(isEnabled()); 115 firstActionContainer.setFocusable(isEnabled()); 116 117 secondActionContainer.setVisibility(mSecondaryActionVisible ? View.VISIBLE : View.GONE); 118 iconView.setImageDrawable(mSecondaryActionIcon); 119 iconView.setEnabled(isSecondaryActionEnabled()); 120 secondaryButton.setEnabled(isSecondaryActionEnabled()); 121 secondaryButton.setFocusable(isSecondaryActionEnabled()); 122 secondaryButton.setOnClickListener(v -> performSecondaryActionClickInternal()); 123 } 124 125 /** 126 * Sets the icon of the secondary action. 127 * 128 * The icon will be tinted to the primary text color, and resized to fit the space. 129 * 130 * @param drawable A {@link Drawable} to set as the icon. 131 */ setSecondaryActionIcon(@ullable Drawable drawable)132 public void setSecondaryActionIcon(@Nullable Drawable drawable) { 133 mSecondaryActionIcon = drawable; 134 notifyChanged(); 135 } 136 137 /** 138 * Sets the icon of the secondary action. 139 * 140 * The icon will be tinted to the primary text color, and resized to fit the space. 141 * 142 * @param resid A drawable resource id to set as the icon. 143 */ setSecondaryActionIcon(@rawableRes int resid)144 public void setSecondaryActionIcon(@DrawableRes int resid) { 145 setSecondaryActionIcon(ContextCompat.getDrawable(getContext(), resid)); 146 } 147 148 /** 149 * Sets the on-click listener of the secondary action button. 150 */ setOnSecondaryActionClickListener(@ullable Runnable onClickListener)151 public void setOnSecondaryActionClickListener(@Nullable Runnable onClickListener) { 152 mSecondaryActionOnClickListener = onClickListener; 153 notifyChanged(); 154 } 155 } 156