blob: 0549b60fd2f30352e33ab927c43ca70e0271594d [file] [log] [blame]
Jason Monk39b46742015-09-10 15:52:51 -04001/*
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
17package com.android.settings;
18
19import android.app.AlertDialog;
Adrian Roosd553f4f2016-02-22 13:03:42 -080020import android.app.Dialog;
Jeff Sharkey4a8136b2016-07-27 12:53:34 -060021import android.app.Fragment;
22import android.app.FragmentTransaction;
Jason Monk39b46742015-09-10 15:52:51 -040023import android.content.Context;
24import android.content.DialogInterface;
Jeff Sharkey4a8136b2016-07-27 12:53:34 -060025import android.content.DialogInterface.OnClickListener;
26import android.content.Intent;
Jason Monk39b46742015-09-10 15:52:51 -040027import android.os.Bundle;
28import android.support.v14.preference.ListPreferenceDialogFragment;
29import android.support.v7.preference.ListPreference;
30import android.util.AttributeSet;
31
Tamas Berghammer265d3c22016-06-22 15:34:45 +010032import com.android.internal.logging.nano.MetricsProto;
Fan Zhangac5e5932016-08-24 18:13:33 -070033import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
34
Julia Reynolds2e1e0b72015-12-14 08:32:46 -050035public class CustomListPreference extends ListPreference {
Jason Monk39b46742015-09-10 15:52:51 -040036
37 public CustomListPreference(Context context, AttributeSet attrs) {
38 super(context, attrs);
39 }
40
41 public CustomListPreference(Context context, AttributeSet attrs, int defStyleAttr,
42 int defStyleRes) {
43 super(context, attrs, defStyleAttr, defStyleRes);
44 }
45
46 protected void onPrepareDialogBuilder(AlertDialog.Builder builder,
47 DialogInterface.OnClickListener listener) {
48 }
49
50 protected void onDialogClosed(boolean positiveResult) {
51 }
52
Adrian Roosd553f4f2016-02-22 13:03:42 -080053 protected void onDialogCreated(Dialog dialog) {
54 }
55
56 protected boolean isAutoClosePreference() {
57 return true;
58 }
59
Jeff Sharkey4a8136b2016-07-27 12:53:34 -060060 /**
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 */
68 protected CharSequence getConfirmationMessage(String value) {
69 return null;
70 }
71
Adrian Roos4bd42072016-04-29 14:37:02 -070072 protected void onDialogStateRestored(Dialog dialog, Bundle savedInstanceState) {
73 }
74
Jason Monk39b46742015-09-10 15:52:51 -040075 public static class CustomListPreferenceDialogFragment extends ListPreferenceDialogFragment {
76
Adrian Roos4bd42072016-04-29 14:37:02 -070077 private static final java.lang.String KEY_CLICKED_ENTRY_INDEX
78 = "settings.CustomListPrefDialog.KEY_CLICKED_ENTRY_INDEX";
79
Jason Monk9cbf3252015-12-14 16:39:45 -050080 private int mClickedDialogEntryIndex;
81
Jason Monk39b46742015-09-10 15:52:51 -040082 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
90 private CustomListPreference getCustomizablePreference() {
91 return (CustomListPreference) getPreference();
92 }
93
94 @Override
95 protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
96 super.onPrepareDialogBuilder(builder);
Jason Monk9cbf3252015-12-14 16:39:45 -050097 mClickedDialogEntryIndex = getCustomizablePreference()
98 .findIndexOfValue(getCustomizablePreference().getValue());
Sudheer Shanka550d0682016-01-13 15:16:55 +000099 getCustomizablePreference().onPrepareDialogBuilder(builder, getOnItemClickListener());
Adrian Roosd553f4f2016-02-22 13:03:42 -0800100 if (!getCustomizablePreference().isAutoClosePreference()) {
101 builder.setPositiveButton(R.string.okay, new DialogInterface.OnClickListener() {
102 @Override
103 public void onClick(DialogInterface dialog, int which) {
Jeff Sharkey4a8136b2016-07-27 12:53:34 -0600104 onItemChosen();
Adrian Roosd553f4f2016-02-22 13:03:42 -0800105 }
106 });
107 }
108 }
109
110 @Override
111 public Dialog onCreateDialog(Bundle savedInstanceState) {
112 Dialog dialog = super.onCreateDialog(savedInstanceState);
Adrian Roos4bd42072016-04-29 14:37:02 -0700113 if (savedInstanceState != null) {
114 mClickedDialogEntryIndex = savedInstanceState.getInt(KEY_CLICKED_ENTRY_INDEX,
115 mClickedDialogEntryIndex);
116 }
Adrian Roosd553f4f2016-02-22 13:03:42 -0800117 getCustomizablePreference().onDialogCreated(dialog);
118 return dialog;
Sudheer Shanka550d0682016-01-13 15:16:55 +0000119 }
Jason Monk9cbf3252015-12-14 16:39:45 -0500120
Adrian Roos4bd42072016-04-29 14:37:02 -0700121 @Override
122 public void onSaveInstanceState(Bundle outState) {
123 super.onSaveInstanceState(outState);
124 outState.putInt(KEY_CLICKED_ENTRY_INDEX, mClickedDialogEntryIndex);
125 }
126
127 @Override
128 public void onActivityCreated(Bundle savedInstanceState) {
129 super.onActivityCreated(savedInstanceState);
130 getCustomizablePreference().onDialogStateRestored(getDialog(), savedInstanceState);
131 }
132
Sudheer Shanka550d0682016-01-13 15:16:55 +0000133 protected DialogInterface.OnClickListener getOnItemClickListener() {
134 return new DialogInterface.OnClickListener() {
Jeff Sharkey4a8136b2016-07-27 12:53:34 -0600135 @Override
Sudheer Shanka550d0682016-01-13 15:16:55 +0000136 public void onClick(DialogInterface dialog, int which) {
137 setClickedDialogEntryIndex(which);
Adrian Roosd553f4f2016-02-22 13:03:42 -0800138 if (getCustomizablePreference().isAutoClosePreference()) {
Jeff Sharkey4a8136b2016-07-27 12:53:34 -0600139 onItemChosen();
Adrian Roosd553f4f2016-02-22 13:03:42 -0800140 }
Sudheer Shanka550d0682016-01-13 15:16:55 +0000141 }
142 };
143 }
144
145 protected void setClickedDialogEntryIndex(int which) {
146 mClickedDialogEntryIndex = which;
Jason Monk39b46742015-09-10 15:52:51 -0400147 }
148
Jeff Sharkey4a8136b2016-07-27 12:53:34 -0600149 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 */
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 */
183 protected void onItemConfirmed() {
184 onClick(getDialog(), DialogInterface.BUTTON_POSITIVE);
185 getDialog().dismiss();
186 }
187
Jason Monk39b46742015-09-10 15:52:51 -0400188 @Override
189 public void onDialogClosed(boolean positiveResult) {
190 getCustomizablePreference().onDialogClosed(positiveResult);
Jason Monk9cbf3252015-12-14 16:39:45 -0500191 final ListPreference preference = getCustomizablePreference();
Jeff Sharkey4a8136b2016-07-27 12:53:34 -0600192 final String value = getValue();
193 if (positiveResult && value != null) {
Jason Monk9cbf3252015-12-14 16:39:45 -0500194 if (preference.callChangeListener(value)) {
195 preference.setValue(value);
196 }
197 }
Jason Monk39b46742015-09-10 15:52:51 -0400198 }
199 }
Jeff Sharkey4a8136b2016-07-27 12:53:34 -0600200
Fan Zhangac5e5932016-08-24 18:13:33 -0700201 public static class ConfirmDialogFragment extends InstrumentedDialogFragment {
Jeff Sharkey4a8136b2016-07-27 12:53:34 -0600202 @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 }
Fan Zhangac5e5932016-08-24 18:13:33 -0700218
219 @Override
220 public int getMetricsCategory() {
221 return MetricsProto.MetricsEvent.DIALOG_CUSTOM_LIST_CONFIRMATION;
222 }
Jeff Sharkey4a8136b2016-07-27 12:53:34 -0600223 }
Jason Monk39b46742015-09-10 15:52:51 -0400224}