• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 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.settings;
18 
19 import android.app.AlertDialog;
20 import android.app.Dialog;
21 import android.app.Fragment;
22 import android.app.FragmentTransaction;
23 import android.content.Context;
24 import android.content.DialogInterface;
25 import android.content.DialogInterface.OnClickListener;
26 import android.content.Intent;
27 import android.os.Bundle;
28 import android.support.v14.preference.ListPreferenceDialogFragment;
29 import android.support.v7.preference.ListPreference;
30 import android.util.AttributeSet;
31 
32 import com.android.internal.logging.nano.MetricsProto;
33 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
34 
35 public class CustomListPreference extends ListPreference {
36 
CustomListPreference(Context context, AttributeSet attrs)37     public CustomListPreference(Context context, AttributeSet attrs) {
38         super(context, attrs);
39     }
40 
CustomListPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)41     public CustomListPreference(Context context, AttributeSet attrs, int defStyleAttr,
42                                 int defStyleRes) {
43         super(context, attrs, defStyleAttr, defStyleRes);
44     }
45 
onPrepareDialogBuilder(AlertDialog.Builder builder, DialogInterface.OnClickListener listener)46     protected void onPrepareDialogBuilder(AlertDialog.Builder builder,
47             DialogInterface.OnClickListener listener) {
48     }
49 
onDialogClosed(boolean positiveResult)50     protected void onDialogClosed(boolean positiveResult) {
51     }
52 
onDialogCreated(Dialog dialog)53     protected void onDialogCreated(Dialog dialog) {
54     }
55 
isAutoClosePreference()56     protected boolean isAutoClosePreference() {
57         return true;
58     }
59 
60     /**
61      * Called when a user is about to choose the given value, to determine if we
62      * should show a confirmation dialog.
63      *
64      * @param value the value the user is about to choose
65      * @return the message to show in a confirmation dialog, or {@code null} to
66      *         not request confirmation
67      */
getConfirmationMessage(String value)68     protected CharSequence getConfirmationMessage(String value) {
69         return null;
70     }
71 
onDialogStateRestored(Dialog dialog, Bundle savedInstanceState)72     protected void onDialogStateRestored(Dialog dialog, Bundle savedInstanceState) {
73     }
74 
75     public static class CustomListPreferenceDialogFragment extends ListPreferenceDialogFragment {
76 
77         private static final java.lang.String KEY_CLICKED_ENTRY_INDEX
78                 = "settings.CustomListPrefDialog.KEY_CLICKED_ENTRY_INDEX";
79 
80         private int mClickedDialogEntryIndex;
81 
newInstance(String key)82         public static ListPreferenceDialogFragment newInstance(String key) {
83             final ListPreferenceDialogFragment fragment = new CustomListPreferenceDialogFragment();
84             final Bundle b = new Bundle(1);
85             b.putString(ARG_KEY, key);
86             fragment.setArguments(b);
87             return fragment;
88         }
89 
getCustomizablePreference()90         private CustomListPreference getCustomizablePreference() {
91             return (CustomListPreference) getPreference();
92         }
93 
94         @Override
onPrepareDialogBuilder(AlertDialog.Builder builder)95         protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
96             super.onPrepareDialogBuilder(builder);
97             mClickedDialogEntryIndex = getCustomizablePreference()
98                     .findIndexOfValue(getCustomizablePreference().getValue());
99             getCustomizablePreference().onPrepareDialogBuilder(builder, getOnItemClickListener());
100             if (!getCustomizablePreference().isAutoClosePreference()) {
101                 builder.setPositiveButton(R.string.okay, new DialogInterface.OnClickListener() {
102                     @Override
103                     public void onClick(DialogInterface dialog, int which) {
104                         onItemChosen();
105                     }
106                 });
107             }
108         }
109 
110         @Override
onCreateDialog(Bundle savedInstanceState)111         public Dialog onCreateDialog(Bundle savedInstanceState) {
112             Dialog dialog = super.onCreateDialog(savedInstanceState);
113             if (savedInstanceState != null) {
114                 mClickedDialogEntryIndex = savedInstanceState.getInt(KEY_CLICKED_ENTRY_INDEX,
115                         mClickedDialogEntryIndex);
116             }
117             getCustomizablePreference().onDialogCreated(dialog);
118             return dialog;
119         }
120 
121         @Override
onSaveInstanceState(Bundle outState)122         public void onSaveInstanceState(Bundle outState) {
123             super.onSaveInstanceState(outState);
124             outState.putInt(KEY_CLICKED_ENTRY_INDEX, mClickedDialogEntryIndex);
125         }
126 
127         @Override
onActivityCreated(Bundle savedInstanceState)128         public void onActivityCreated(Bundle savedInstanceState) {
129             super.onActivityCreated(savedInstanceState);
130             getCustomizablePreference().onDialogStateRestored(getDialog(), savedInstanceState);
131         }
132 
getOnItemClickListener()133         protected DialogInterface.OnClickListener getOnItemClickListener() {
134             return new DialogInterface.OnClickListener() {
135                 @Override
136                 public void onClick(DialogInterface dialog, int which) {
137                     setClickedDialogEntryIndex(which);
138                     if (getCustomizablePreference().isAutoClosePreference()) {
139                         onItemChosen();
140                     }
141                 }
142             };
143         }
144 
setClickedDialogEntryIndex(int which)145         protected void setClickedDialogEntryIndex(int which) {
146             mClickedDialogEntryIndex = which;
147         }
148 
getValue()149         private String getValue() {
150             final ListPreference preference = getCustomizablePreference();
151             if (mClickedDialogEntryIndex >= 0 && preference.getEntryValues() != null) {
152                 return preference.getEntryValues()[mClickedDialogEntryIndex].toString();
153             } else {
154                 return null;
155             }
156         }
157 
158         /**
159          * Called when user has made a concrete item choice, but we might need
160          * to make a quick detour to confirm that choice with a second dialog.
161          */
onItemChosen()162         protected void onItemChosen() {
163             final CharSequence message = getCustomizablePreference()
164                     .getConfirmationMessage(getValue());
165             if (message != null) {
166                 final Fragment f = new ConfirmDialogFragment();
167                 final Bundle args = new Bundle();
168                 args.putCharSequence(Intent.EXTRA_TEXT, message);
169                 f.setArguments(args);
170                 f.setTargetFragment(CustomListPreferenceDialogFragment.this, 0);
171                 final FragmentTransaction ft = getFragmentManager().beginTransaction();
172                 ft.add(f, getTag() + "-Confirm");
173                 ft.commitAllowingStateLoss();
174             } else {
175                 onItemConfirmed();
176             }
177         }
178 
179         /**
180          * Called when user has made a concrete item choice and we've fully
181          * confirmed they want to move forward (if we took a detour above).
182          */
onItemConfirmed()183         protected void onItemConfirmed() {
184             onClick(getDialog(), DialogInterface.BUTTON_POSITIVE);
185             getDialog().dismiss();
186         }
187 
188         @Override
onDialogClosed(boolean positiveResult)189         public void onDialogClosed(boolean positiveResult) {
190             getCustomizablePreference().onDialogClosed(positiveResult);
191             final ListPreference preference = getCustomizablePreference();
192             final String value = getValue();
193             if (positiveResult && value != null) {
194                 if (preference.callChangeListener(value)) {
195                     preference.setValue(value);
196                 }
197             }
198         }
199     }
200 
201     public static class ConfirmDialogFragment extends InstrumentedDialogFragment {
202         @Override
203         public Dialog onCreateDialog(Bundle savedInstanceState) {
204             return new AlertDialog.Builder(getActivity())
205                     .setMessage(getArguments().getCharSequence(Intent.EXTRA_TEXT))
206                     .setPositiveButton(android.R.string.ok, new OnClickListener() {
207                         @Override
208                         public void onClick(DialogInterface dialog, int which) {
209                             final Fragment f = getTargetFragment();
210                             if (f != null) {
211                                 ((CustomListPreferenceDialogFragment) f).onItemConfirmed();
212                             }
213                         }
214                     })
215                     .setNegativeButton(android.R.string.cancel, null)
216                     .create();
217         }
218 
219         @Override
220         public int getMetricsCategory() {
221             return MetricsProto.MetricsEvent.DIALOG_CUSTOM_LIST_CONFIRMATION;
222         }
223     }
224 }
225