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.car.settings.common; 18 19 import android.car.drivingstate.CarUxRestrictions; 20 import android.content.Context; 21 import android.text.TextUtils; 22 23 import androidx.annotation.NonNull; 24 import androidx.preference.PreferenceGroup; 25 import androidx.preference.TwoStatePreference; 26 27 import java.util.List; 28 29 /** 30 * A preference controller which ensure that only one of many {@link TwoStatePreference} 31 * instances can be checked at any given point in time. 32 * 33 * <p>The behavior of this class is not well defined if multiple preferences have the same key. 34 */ 35 public abstract class GroupSelectionPreferenceController extends 36 PreferenceController<PreferenceGroup> { 37 GroupSelectionPreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions)38 public GroupSelectionPreferenceController(Context context, String preferenceKey, 39 FragmentController fragmentController, CarUxRestrictions uxRestrictions) { 40 super(context, preferenceKey, fragmentController, uxRestrictions); 41 } 42 43 @Override getPreferenceType()44 protected Class<PreferenceGroup> getPreferenceType() { 45 return PreferenceGroup.class; 46 } 47 48 @Override updateState(PreferenceGroup preferenceGroup)49 protected final void updateState(PreferenceGroup preferenceGroup) { 50 List<TwoStatePreference> items = getGroupPreferences(); 51 preferenceGroup.removeAll(); 52 for (TwoStatePreference preference : items) { 53 54 preference.setOnPreferenceClickListener(pref -> { 55 if (handleGroupItemSelected(preference)) { 56 notifyCheckedKeyChanged(); 57 } 58 return true; 59 }); 60 // All changes to the checked state will happen programmatically if using this 61 // class. 62 preference.setOnPreferenceChangeListener((pref, o) -> false); 63 preference.setPersistent(false); 64 preferenceGroup.addPreference(preference); 65 } 66 67 notifyCheckedKeyChanged(); 68 } 69 70 /** Returns the value of the currently checked key. */ getCurrentCheckedKey()71 protected abstract String getCurrentCheckedKey(); 72 73 /** Returns the list of preferences that should be available to select in this group. */ 74 @NonNull getGroupPreferences()75 protected abstract List<TwoStatePreference> getGroupPreferences(); 76 77 /** 78 * Intercepts a click action on an item in the group. Refreshes the UI immediately if returns 79 * {@code true}. Otherwise {@link #notifyCheckedKeyChanged()} can be used when the selected key 80 * has changed. 81 */ handleGroupItemSelected(TwoStatePreference preference)82 protected boolean handleGroupItemSelected(TwoStatePreference preference) { 83 return true; 84 } 85 86 /** Refreshes the checked state of the preferences in the {@link PreferenceGroup}. */ notifyCheckedKeyChanged()87 protected void notifyCheckedKeyChanged() { 88 for (int i = 0; i < getPreference().getPreferenceCount(); i++) { 89 TwoStatePreference preference = (TwoStatePreference) getPreference().getPreference(i); 90 preference.setChecked(TextUtils.equals(preference.getKey(), getCurrentCheckedKey())); 91 } 92 } 93 } 94