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.util.AttributeSet;
24 import android.view.View;
25 import android.widget.Button;
26 
27 import androidx.annotation.Nullable;
28 import androidx.annotation.StringRes;
29 import androidx.preference.PreferenceViewHolder;
30 
31 import com.android.car.ui.R;
32 import com.android.car.ui.utils.CarUiUtils;
33 
34 /**
35  * A preference that has a text button that can be pressed independently of pressing the main
36  * body of the preference.
37  */
38 @SuppressWarnings("AndroidJdkLibsChecker")
39 public class CarUiTwoActionTextPreference extends CarUiTwoActionBasePreference {
40 
41     @Nullable
42     protected Runnable mSecondaryActionOnClickListener;
43     @Nullable
44     private CharSequence mSecondaryActionText;
45 
CarUiTwoActionTextPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)46     public CarUiTwoActionTextPreference(Context context,
47             AttributeSet attrs,
48             int defStyleAttr, int defStyleRes) {
49         super(context, attrs, defStyleAttr, defStyleRes);
50     }
51 
CarUiTwoActionTextPreference(Context context, AttributeSet attrs, int defStyleAttr)52     public CarUiTwoActionTextPreference(Context context, AttributeSet attrs, int defStyleAttr) {
53         super(context, attrs, defStyleAttr);
54     }
55 
CarUiTwoActionTextPreference(Context context, AttributeSet attrs)56     public CarUiTwoActionTextPreference(Context context, AttributeSet attrs) {
57         super(context, attrs);
58     }
59 
CarUiTwoActionTextPreference(Context context)60     public CarUiTwoActionTextPreference(Context context) {
61         super(context);
62     }
63 
64     @Override
init(@ullable AttributeSet attrs)65     protected void init(@Nullable AttributeSet attrs) {
66         super.init(attrs);
67 
68         TypedArray a = getContext().obtainStyledAttributes(attrs,
69                 R.styleable.CarUiTwoActionTextPreference);
70         int actionStyle = 0;
71         try {
72             actionStyle = a.getInteger(
73                     R.styleable.CarUiTwoActionTextPreference_secondaryActionStyle, 0);
74             mSecondaryActionText = a.getString(
75                     R.styleable.CarUiTwoActionTextPreference_secondaryActionText);
76         } finally {
77             a.recycle();
78         }
79 
80         setLayoutResourceInternal(actionStyle == 0
81                 ? R.layout.car_ui_preference_two_action_text
82                 : R.layout.car_ui_preference_two_action_text_borderless);
83     }
84 
85     @Override
performSecondaryActionClickInternal()86     protected void performSecondaryActionClickInternal() {
87         if (mSecondaryActionOnClickListener != null) {
88             mSecondaryActionOnClickListener.run();
89         }
90     }
91 
92     @Override
onBindViewHolder(PreferenceViewHolder holder)93     public void onBindViewHolder(PreferenceViewHolder holder) {
94         super.onBindViewHolder(holder);
95 
96         View firstActionContainer = requireViewByRefId(holder.itemView,
97                 R.id.car_ui_first_action_container);
98         View secondActionContainer = requireViewByRefId(holder.itemView,
99                 R.id.car_ui_second_action_container);
100         Button secondaryButton = requireViewByRefId(holder.itemView,
101                 R.id.car_ui_secondary_action);
102 
103         holder.itemView.setFocusable(false);
104         holder.itemView.setClickable(false);
105         firstActionContainer.setOnClickListener(this::performClickUnrestricted);
106         firstActionContainer.setEnabled(isEnabled() || isClickableWhileDisabled());
107         firstActionContainer.setFocusable(isEnabled() || isClickableWhileDisabled());
108 
109         secondActionContainer.setVisibility(mSecondaryActionVisible ? View.VISIBLE : View.GONE);
110         secondaryButton.setText(mSecondaryActionText);
111         secondaryButton.setOnClickListener(v -> performSecondaryActionClick());
112         secondaryButton.setEnabled(isSecondaryActionEnabled() || isClickableWhileDisabled());
113         secondaryButton.setFocusable(isSecondaryActionEnabled() || isClickableWhileDisabled());
114 
115         CarUiUtils.makeAllViewsEnabledAndUxRestricted(secondaryButton, isSecondaryActionEnabled(),
116                 isUxRestricted());
117     }
118 
119     @Nullable
getSecondaryActionText()120     public CharSequence getSecondaryActionText() {
121         return mSecondaryActionText;
122     }
123 
124     /**
125      * Sets the title of the secondary action button.
126      *
127      * @param title The text to display on the secondary action.
128      */
setSecondaryActionText(@ullable CharSequence title)129     public void setSecondaryActionText(@Nullable CharSequence title) {
130         mSecondaryActionText = title;
131         notifyChanged();
132     }
133 
134     /**
135      * Sets the title of the secondary action button.
136      *
137      * @param resid A string resource of the text to display on the secondary action.
138      */
setSecondaryActionText(@tringRes int resid)139     public void setSecondaryActionText(@StringRes int resid) {
140         setSecondaryActionText(getContext().getString(resid));
141     }
142 
143     /**
144      * Sets the on-click listener of the secondary action button.
145      */
setOnSecondaryActionClickListener(@ullable Runnable onClickListener)146     public void setOnSecondaryActionClickListener(@Nullable Runnable onClickListener) {
147         mSecondaryActionOnClickListener = onClickListener;
148         notifyChanged();
149     }
150 }
151