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