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