1 /* 2 * Copyright (C) 2021 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.util.AttributeSet; 21 import android.view.View; 22 import android.widget.AdapterView; 23 24 import androidx.preference.Preference; 25 import androidx.preference.Preference.OnPreferenceClickListener; 26 import androidx.preference.PreferenceViewHolder; 27 28 import com.android.settingslib.widget.settingsspinner.SettingsSpinner; 29 import com.android.settingslib.widget.settingsspinner.SettingsSpinnerAdapter; 30 31 /** 32 * This preference uses SettingsSpinner & SettingsSpinnerAdapter which provide default layouts for 33 * both view and drop down view of the Spinner. 34 */ 35 public class SettingsSpinnerPreference extends Preference implements OnPreferenceClickListener { 36 37 private SettingsSpinnerAdapter mAdapter; 38 private AdapterView.OnItemSelectedListener mListener; 39 private int mPosition; 40 private boolean mShouldPerformClick; 41 42 /** 43 * Perform inflation from XML and apply a class-specific base style. 44 * 45 * @param context The {@link Context} this is associated with, through which it can 46 * access the current theme, resources, {@link SharedPreferences}, etc. 47 * @param attrs The attributes of the XML tag that is inflating the preference 48 * @param defStyle An attribute in the current theme that contains a reference to a style 49 * resource that supplies default values for the view. Can be 0 to not 50 * look for defaults. 51 */ SettingsSpinnerPreference(Context context, AttributeSet attrs, int defStyle)52 public SettingsSpinnerPreference(Context context, AttributeSet attrs, int defStyle) { 53 super(context, attrs, defStyle); 54 setLayoutResource(R.layout.settings_spinner_preference); 55 setOnPreferenceClickListener(this); 56 } 57 58 /** 59 * Perform inflation from XML and apply a class-specific base style. 60 * 61 * @param context The {@link Context} this is associated with, through which it can 62 * access the current theme, resources, {@link SharedPreferences}, etc. 63 * @param attrs The attributes of the XML tag that is inflating the preference 64 */ SettingsSpinnerPreference(Context context, AttributeSet attrs)65 public SettingsSpinnerPreference(Context context, AttributeSet attrs) { 66 super(context, attrs); 67 setLayoutResource(R.layout.settings_spinner_preference); 68 setOnPreferenceClickListener(this); 69 } 70 71 /** 72 * Constructor to create a preference. 73 * 74 * @param context The Context this is associated with. 75 */ SettingsSpinnerPreference(Context context)76 public SettingsSpinnerPreference(Context context) { 77 this(context, null); 78 } 79 80 @Override onPreferenceClick(Preference preference)81 public boolean onPreferenceClick(Preference preference) { 82 mShouldPerformClick = true; 83 notifyChanged(); 84 return true; 85 } 86 87 /** Sets adapter of the spinner. */ setAdapter(T adapter)88 public <T extends SettingsSpinnerAdapter> void setAdapter(T adapter) { 89 mAdapter = adapter; 90 notifyChanged(); 91 } 92 93 /** Sets item selection listener of the spinner. */ setOnItemSelectedListener(AdapterView.OnItemSelectedListener listener)94 public void setOnItemSelectedListener(AdapterView.OnItemSelectedListener listener) { 95 mListener = listener; 96 } 97 98 /** Gets selected item of the spinner. */ getSelectedItem()99 public Object getSelectedItem() { 100 return mAdapter == null ? null : mAdapter.getItem(mPosition); 101 } 102 103 /** Gets selection position of the spinner */ setSelection(int position)104 public void setSelection(int position) { 105 if (mPosition == position) { 106 return; 107 } 108 mPosition = position; 109 notifyChanged(); 110 } 111 112 113 @Override onBindViewHolder(PreferenceViewHolder holder)114 public void onBindViewHolder(PreferenceViewHolder holder) { 115 super.onBindViewHolder(holder); 116 final SettingsSpinner spinner = (SettingsSpinner) holder.findViewById(R.id.spinner); 117 spinner.setAdapter(mAdapter); 118 spinner.setSelection(mPosition); 119 spinner.setOnItemSelectedListener(mOnSelectedListener); 120 if (mShouldPerformClick) { 121 mShouldPerformClick = false; 122 // To show dropdown view. 123 spinner.performClick(); 124 } 125 } 126 127 private final AdapterView.OnItemSelectedListener mOnSelectedListener = 128 new AdapterView.OnItemSelectedListener() { 129 @Override 130 public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { 131 if (mPosition == position) return; 132 mPosition = position; 133 if (mListener != null) { 134 mListener.onItemSelected(parent, view, position, id); 135 } 136 } 137 138 @Override 139 public void onNothingSelected(AdapterView<?> parent) { 140 if (mListener != null) { 141 mListener.onNothingSelected(parent); 142 } 143 } 144 }; 145 } 146