• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 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 package com.android.settings.widget;
17 
18 import android.app.AlertDialog;
19 import android.content.res.TypedArray;
20 import android.os.Bundle;
21 import android.support.annotation.VisibleForTesting;
22 import android.support.v14.preference.PreferenceDialogFragment;
23 import android.support.v7.preference.ListPreference;
24 import android.widget.ArrayAdapter;
25 import com.android.settingslib.core.instrumentation.Instrumentable;
26 
27 import java.util.ArrayList;
28 
29 /**
30  * {@link PreferenceDialogFragment} that updates the available options
31  * when {@code onListPreferenceUpdated} is called."
32  */
33 public class UpdatableListPreferenceDialogFragment extends PreferenceDialogFragment implements
34         Instrumentable {
35 
36     private static final String SAVE_STATE_INDEX = "UpdatableListPreferenceDialogFragment.index";
37     private static final String SAVE_STATE_ENTRIES =
38             "UpdatableListPreferenceDialogFragment.entries";
39     private static final String SAVE_STATE_ENTRY_VALUES =
40             "UpdatableListPreferenceDialogFragment.entryValues";
41     private static final String METRICS_CATEGORY_KEY = "metrics_category_key";
42     private ArrayAdapter mAdapter;
43     private int mClickedDialogEntryIndex;
44     private ArrayList<CharSequence> mEntries;
45     private CharSequence[] mEntryValues;
46     private int mMetricsCategory = Instrumentable.METRICS_CATEGORY_UNKNOWN;
47 
newInstance( String key, int metricsCategory)48     public static UpdatableListPreferenceDialogFragment newInstance(
49             String key, int metricsCategory) {
50         UpdatableListPreferenceDialogFragment fragment =
51                 new UpdatableListPreferenceDialogFragment();
52         Bundle args = new Bundle(1);
53         args.putString(ARG_KEY, key);
54         args.putInt(METRICS_CATEGORY_KEY, metricsCategory);
55         fragment.setArguments(args);
56         return fragment;
57     }
58 
onCreate(Bundle savedInstanceState)59     public void onCreate(Bundle savedInstanceState) {
60         super.onCreate(savedInstanceState);
61         final Bundle bundle = getArguments();
62         mMetricsCategory =
63                 bundle.getInt(METRICS_CATEGORY_KEY, Instrumentable.METRICS_CATEGORY_UNKNOWN);
64         if (savedInstanceState == null) {
65             mEntries = new ArrayList<>();
66             setPreferenceData(getListPreference());
67         } else {
68             mClickedDialogEntryIndex = savedInstanceState.getInt(SAVE_STATE_INDEX, 0);
69             mEntries = savedInstanceState.getCharSequenceArrayList(SAVE_STATE_ENTRIES);
70             mEntryValues =
71                     savedInstanceState.getCharSequenceArray(SAVE_STATE_ENTRY_VALUES);
72         }
73     }
74 
75     @Override
onSaveInstanceState(Bundle outState)76     public void onSaveInstanceState(Bundle outState) {
77         super.onSaveInstanceState(outState);
78         outState.putInt(SAVE_STATE_INDEX, mClickedDialogEntryIndex);
79         outState.putCharSequenceArrayList(SAVE_STATE_ENTRIES, mEntries);
80         outState.putCharSequenceArray(SAVE_STATE_ENTRY_VALUES, mEntryValues);
81     }
82 
83     @Override
onDialogClosed(boolean positiveResult)84     public void onDialogClosed(boolean positiveResult) {
85         final ListPreference preference = getListPreference();
86         if (positiveResult && mClickedDialogEntryIndex >= 0) {
87             final String value = mEntryValues[mClickedDialogEntryIndex].toString();
88             if (preference.callChangeListener(value)) {
89                 preference.setValue(value);
90             }
91         }
92     }
93 
94     @VisibleForTesting
setAdapter(ArrayAdapter adapter)95     void setAdapter(ArrayAdapter adapter) {
96         mAdapter = adapter;
97     }
98 
99     @VisibleForTesting
setEntries(ArrayList<CharSequence> entries)100     void setEntries(ArrayList<CharSequence> entries) {
101         mEntries = entries;
102     }
103 
104     @VisibleForTesting
getAdapter()105     ArrayAdapter getAdapter() {
106         return mAdapter;
107     }
108 
109     @VisibleForTesting
setMetricsCategory(Bundle bundle)110     void setMetricsCategory(Bundle bundle) {
111         mMetricsCategory =
112                 bundle.getInt(METRICS_CATEGORY_KEY, Instrumentable.METRICS_CATEGORY_UNKNOWN);
113     }
114 
115     @Override
onPrepareDialogBuilder(AlertDialog.Builder builder)116     protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
117         super.onPrepareDialogBuilder(builder);
118         final TypedArray a = getContext().obtainStyledAttributes(
119                 null,
120                 com.android.internal.R.styleable.AlertDialog,
121                 com.android.internal.R.attr.alertDialogStyle, 0);
122 
123         mAdapter = new ArrayAdapter<>(
124                 getContext(),
125                 a.getResourceId(
126                         com.android.internal.R.styleable.AlertDialog_singleChoiceItemLayout,
127                         com.android.internal.R.layout.select_dialog_singlechoice),
128                 mEntries);
129 
130         builder.setSingleChoiceItems(mAdapter, mClickedDialogEntryIndex,
131                 (dialog, which) -> {
132                     mClickedDialogEntryIndex = which;
133                     onClick(dialog, -1);
134                     dialog.dismiss();
135                 });
136         builder.setPositiveButton(null, null);
137         a.recycle();
138     }
139 
140     @Override
getMetricsCategory()141     public int getMetricsCategory() {
142         return mMetricsCategory;
143     }
144 
getListPreference()145     private ListPreference getListPreference() {
146         return (ListPreference) getPreference();
147     }
148 
setPreferenceData(ListPreference preference)149     private void setPreferenceData(ListPreference preference) {
150         mEntries.clear();
151         mClickedDialogEntryIndex = preference.findIndexOfValue(preference.getValue());
152         for (CharSequence entry : preference.getEntries()) {
153             mEntries.add(entry);
154         }
155         mEntryValues = preference.getEntryValues();
156     }
157 
onListPreferenceUpdated(ListPreference preference)158     public void onListPreferenceUpdated(ListPreference preference) {
159         if (mAdapter != null) {
160             setPreferenceData(preference);
161             mAdapter.notifyDataSetChanged();
162         }
163     }
164 }
165