1 /* 2 * Copyright (C) 2019 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.settingslib.widget; 18 19 import android.content.Context; 20 import android.text.TextUtils; 21 import android.util.AttributeSet; 22 import android.view.View; 23 import android.widget.ImageView; 24 25 import androidx.preference.CheckBoxPreference; 26 import androidx.preference.PreferenceViewHolder; 27 28 /** 29 * Check box preference with check box replaced by radio button. 30 * 31 * Functionally speaking, it's actually a CheckBoxPreference. We only modified 32 * the widget to RadioButton to make it "look like" a RadioButtonPreference. 33 * 34 * In other words, there's no "RadioButtonPreferenceGroup" in this 35 * implementation. When you check one RadioButtonPreference, if you want to 36 * uncheck all the other preferences, you should do that by code yourself. 37 * 38 * RadioButtonPreference can assign a extraWidgetListener to show a gear icon 39 * on the right side that can open another page. 40 */ 41 public class RadioButtonPreference extends CheckBoxPreference { 42 43 /** 44 * Interface definition for a callback to be invoked when the preference is clicked. 45 */ 46 public interface OnClickListener { 47 /** 48 * Called when a preference has been clicked. 49 * 50 * @param emiter The clicked preference 51 */ onRadioButtonClicked(RadioButtonPreference emiter)52 void onRadioButtonClicked(RadioButtonPreference emiter); 53 } 54 55 private OnClickListener mListener = null; 56 private View mAppendix; 57 private int mAppendixVisibility = -1; 58 59 private View mExtraWidgetContainer; 60 private ImageView mExtraWidget; 61 62 private View.OnClickListener mExtraWidgetOnClickListener; 63 64 /** 65 * Perform inflation from XML and apply a class-specific base style. 66 * 67 * @param context The {@link Context} this is associated with, through which it can 68 * access the current theme, resources, {@link SharedPreferences}, etc. 69 * @param attrs The attributes of the XML tag that is inflating the preference 70 * @param defStyle An attribute in the current theme that contains a reference to a style 71 * resource that supplies default values for the view. Can be 0 to not 72 * look for defaults. 73 */ RadioButtonPreference(Context context, AttributeSet attrs, int defStyle)74 public RadioButtonPreference(Context context, AttributeSet attrs, int defStyle) { 75 super(context, attrs, defStyle); 76 init(); 77 } 78 79 /** 80 * Perform inflation from XML and apply a class-specific base style. 81 * 82 * @param context The {@link Context} this is associated with, through which it can 83 * access the current theme, resources, {@link SharedPreferences}, etc. 84 * @param attrs The attributes of the XML tag that is inflating the preference 85 */ RadioButtonPreference(Context context, AttributeSet attrs)86 public RadioButtonPreference(Context context, AttributeSet attrs) { 87 super(context, attrs); 88 init(); 89 } 90 91 /** 92 * Constructor to create a preference. 93 * 94 * @param context The Context this is associated with. 95 */ RadioButtonPreference(Context context)96 public RadioButtonPreference(Context context) { 97 this(context, null); 98 } 99 100 /** 101 * Sets the callback to be invoked when this preference is clicked by the user. 102 * 103 * @param listener The callback to be invoked 104 */ setOnClickListener(OnClickListener listener)105 public void setOnClickListener(OnClickListener listener) { 106 mListener = listener; 107 } 108 109 /** 110 * Processes a click on the preference. 111 */ 112 @Override onClick()113 public void onClick() { 114 if (mListener != null) { 115 mListener.onRadioButtonClicked(this); 116 } 117 } 118 119 /** 120 * Binds the created View to the data for this preference. 121 * 122 * <p>This is a good place to grab references to custom Views in the layout and set 123 * properties on them. 124 * 125 * <p>Make sure to call through to the superclass's implementation. 126 * 127 * @param holder The ViewHolder that provides references to the views to fill in. These views 128 * will be recycled, so you should not hold a reference to them after this method 129 * returns. 130 */ 131 @Override onBindViewHolder(PreferenceViewHolder holder)132 public void onBindViewHolder(PreferenceViewHolder holder) { 133 super.onBindViewHolder(holder); 134 135 View summaryContainer = holder.findViewById(R.id.summary_container); 136 if (summaryContainer != null) { 137 summaryContainer.setVisibility( 138 TextUtils.isEmpty(getSummary()) ? View.GONE : View.VISIBLE); 139 mAppendix = holder.findViewById(R.id.appendix); 140 if (mAppendix != null && mAppendixVisibility != -1) { 141 mAppendix.setVisibility(mAppendixVisibility); 142 } 143 } 144 145 mExtraWidget = (ImageView) holder.findViewById(R.id.radio_extra_widget); 146 mExtraWidgetContainer = holder.findViewById(R.id.radio_extra_widget_container); 147 148 setExtraWidgetOnClickListener(mExtraWidgetOnClickListener); 149 } 150 151 /** 152 * Set the visibility state of appendix view. 153 * 154 * @param visibility One of {@link View#VISIBLE}, {@link View#INVISIBLE}, or {@link View#GONE}. 155 */ setAppendixVisibility(int visibility)156 public void setAppendixVisibility(int visibility) { 157 if (mAppendix != null) { 158 mAppendix.setVisibility(visibility); 159 } 160 mAppendixVisibility = visibility; 161 } 162 163 /** 164 * Sets the callback to be invoked when extra widget is clicked by the user. 165 * 166 * @param listener The callback to be invoked 167 */ setExtraWidgetOnClickListener(View.OnClickListener listener)168 public void setExtraWidgetOnClickListener(View.OnClickListener listener) { 169 mExtraWidgetOnClickListener = listener; 170 171 if (mExtraWidget == null || mExtraWidgetContainer == null) { 172 return; 173 } 174 175 mExtraWidget.setOnClickListener(mExtraWidgetOnClickListener); 176 177 mExtraWidgetContainer.setVisibility((mExtraWidgetOnClickListener != null) 178 ? View.VISIBLE : View.GONE); 179 } 180 init()181 private void init() { 182 setWidgetLayoutResource(R.layout.preference_widget_radiobutton); 183 setLayoutResource(R.layout.preference_radio); 184 setIconSpaceReserved(false); 185 } 186 } 187