blob: 978858b1bc38456755eb49e5d64cb20864246786 [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
Adrian Roosd553f4f2016-02-22 13:03:42 -080019import android.app.Dialog;
Fan Zhang31b21002019-01-16 13:49:47 -080020import android.app.settings.SettingsEnums;
Jason Monk39b46742015-09-10 15:52:51 -040021import android.content.Context;
22import android.content.DialogInterface;
Jeff Sharkey4a8136b2016-07-27 12:53:34 -060023import android.content.DialogInterface.OnClickListener;
24import android.content.Intent;
Jason Monk39b46742015-09-10 15:52:51 -040025import android.os.Bundle;
Jason Monk39b46742015-09-10 15:52:51 -040026import android.util.AttributeSet;
27
tmfang27c84de2018-06-28 11:39:05 +080028import androidx.appcompat.app.AlertDialog.Builder;
tmfang99cc23d2018-06-26 19:01:57 +080029import androidx.fragment.app.Fragment;
30import androidx.fragment.app.FragmentTransaction;
Fan Zhangc7162cd2018-06-18 15:21:41 -070031import androidx.preference.ListPreference;
tmfang27c84de2018-06-28 11:39:05 +080032import androidx.preference.ListPreferenceDialogFragmentCompat;
Fan Zhangc7162cd2018-06-18 15:21:41 -070033
Fan Zhang23f8d592018-08-28 15:11:40 -070034import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
35
Julia Reynolds2e1e0b72015-12-14 08:32:46 -050036public class CustomListPreference extends ListPreference {
Jason Monk39b46742015-09-10 15:52:51 -040037
38 public CustomListPreference(Context context, AttributeSet attrs) {
39 super(context, attrs);
40 }
41
42 public CustomListPreference(Context context, AttributeSet attrs, int defStyleAttr,
Fan Zhangfb5bc062018-07-13 14:21:15 -070043 int defStyleRes) {
Jason Monk39b46742015-09-10 15:52:51 -040044 super(context, attrs, defStyleAttr, defStyleRes);
45 }
46
tmfang27c84de2018-06-28 11:39:05 +080047 protected void onPrepareDialogBuilder(Builder builder,
Jason Monk39b46742015-09-10 15:52:51 -040048 DialogInterface.OnClickListener listener) {
49 }
50
51 protected void onDialogClosed(boolean positiveResult) {
52 }
53
Adrian Roosd553f4f2016-02-22 13:03:42 -080054 protected void onDialogCreated(Dialog dialog) {
55 }
56
57 protected boolean isAutoClosePreference() {
58 return true;
59 }
60
Jeff Sharkey4a8136b2016-07-27 12:53:34 -060061 /**
62 * Called when a user is about to choose the given value, to determine if we
63 * should show a confirmation dialog.
64 *
65 * @param value the value the user is about to choose
66 * @return the message to show in a confirmation dialog, or {@code null} to
Fan Zhangfb5bc062018-07-13 14:21:15 -070067 * not request confirmation
Jeff Sharkey4a8136b2016-07-27 12:53:34 -060068 */
69 protected CharSequence getConfirmationMessage(String value) {
70 return null;
71 }
72
Adrian Roos4bd42072016-04-29 14:37:02 -070073 protected void onDialogStateRestored(Dialog dialog, Bundle savedInstanceState) {
74 }
75
tmfang27c84de2018-06-28 11:39:05 +080076 public static class CustomListPreferenceDialogFragment extends
77 ListPreferenceDialogFragmentCompat {
Jason Monk39b46742015-09-10 15:52:51 -040078
Adrian Roos4bd42072016-04-29 14:37:02 -070079 private static final java.lang.String KEY_CLICKED_ENTRY_INDEX
80 = "settings.CustomListPrefDialog.KEY_CLICKED_ENTRY_INDEX";
81
Jason Monk9cbf3252015-12-14 16:39:45 -050082 private int mClickedDialogEntryIndex;
83
tmfang27c84de2018-06-28 11:39:05 +080084 public static ListPreferenceDialogFragmentCompat newInstance(String key) {
85 final ListPreferenceDialogFragmentCompat fragment =
86 new CustomListPreferenceDialogFragment();
Jason Monk39b46742015-09-10 15:52:51 -040087 final Bundle b = new Bundle(1);
88 b.putString(ARG_KEY, key);
89 fragment.setArguments(b);
90 return fragment;
91 }
92
93 private CustomListPreference getCustomizablePreference() {
94 return (CustomListPreference) getPreference();
95 }
96
97 @Override
tmfang27c84de2018-06-28 11:39:05 +080098 protected void onPrepareDialogBuilder(Builder builder) {
Jason Monk39b46742015-09-10 15:52:51 -040099 super.onPrepareDialogBuilder(builder);
Jason Monk9cbf3252015-12-14 16:39:45 -0500100 mClickedDialogEntryIndex = getCustomizablePreference()
101 .findIndexOfValue(getCustomizablePreference().getValue());
Sudheer Shanka550d0682016-01-13 15:16:55 +0000102 getCustomizablePreference().onPrepareDialogBuilder(builder, getOnItemClickListener());
Adrian Roosd553f4f2016-02-22 13:03:42 -0800103 if (!getCustomizablePreference().isAutoClosePreference()) {
104 builder.setPositiveButton(R.string.okay, new DialogInterface.OnClickListener() {
105 @Override
106 public void onClick(DialogInterface dialog, int which) {
Jeff Sharkey4a8136b2016-07-27 12:53:34 -0600107 onItemChosen();
Adrian Roosd553f4f2016-02-22 13:03:42 -0800108 }
109 });
110 }
111 }
112
113 @Override
114 public Dialog onCreateDialog(Bundle savedInstanceState) {
115 Dialog dialog = super.onCreateDialog(savedInstanceState);
Adrian Roos4bd42072016-04-29 14:37:02 -0700116 if (savedInstanceState != null) {
117 mClickedDialogEntryIndex = savedInstanceState.getInt(KEY_CLICKED_ENTRY_INDEX,
118 mClickedDialogEntryIndex);
119 }
Adrian Roosd553f4f2016-02-22 13:03:42 -0800120 getCustomizablePreference().onDialogCreated(dialog);
121 return dialog;
Sudheer Shanka550d0682016-01-13 15:16:55 +0000122 }
Jason Monk9cbf3252015-12-14 16:39:45 -0500123
Adrian Roos4bd42072016-04-29 14:37:02 -0700124 @Override
125 public void onSaveInstanceState(Bundle outState) {
126 super.onSaveInstanceState(outState);
127 outState.putInt(KEY_CLICKED_ENTRY_INDEX, mClickedDialogEntryIndex);
128 }
129
130 @Override
131 public void onActivityCreated(Bundle savedInstanceState) {
132 super.onActivityCreated(savedInstanceState);
133 getCustomizablePreference().onDialogStateRestored(getDialog(), savedInstanceState);
134 }
135
Sudheer Shanka550d0682016-01-13 15:16:55 +0000136 protected DialogInterface.OnClickListener getOnItemClickListener() {
137 return new DialogInterface.OnClickListener() {
Jeff Sharkey4a8136b2016-07-27 12:53:34 -0600138 @Override
Sudheer Shanka550d0682016-01-13 15:16:55 +0000139 public void onClick(DialogInterface dialog, int which) {
140 setClickedDialogEntryIndex(which);
Adrian Roosd553f4f2016-02-22 13:03:42 -0800141 if (getCustomizablePreference().isAutoClosePreference()) {
Jeff Sharkey4a8136b2016-07-27 12:53:34 -0600142 onItemChosen();
Adrian Roosd553f4f2016-02-22 13:03:42 -0800143 }
Sudheer Shanka550d0682016-01-13 15:16:55 +0000144 }
145 };
146 }
147
148 protected void setClickedDialogEntryIndex(int which) {
149 mClickedDialogEntryIndex = which;
Jason Monk39b46742015-09-10 15:52:51 -0400150 }
151
Jeff Sharkey4a8136b2016-07-27 12:53:34 -0600152 private String getValue() {
153 final ListPreference preference = getCustomizablePreference();
154 if (mClickedDialogEntryIndex >= 0 && preference.getEntryValues() != null) {
155 return preference.getEntryValues()[mClickedDialogEntryIndex].toString();
156 } else {
157 return null;
158 }
159 }
160
161 /**
162 * Called when user has made a concrete item choice, but we might need
163 * to make a quick detour to confirm that choice with a second dialog.
164 */
165 protected void onItemChosen() {
166 final CharSequence message = getCustomizablePreference()
167 .getConfirmationMessage(getValue());
168 if (message != null) {
169 final Fragment f = new ConfirmDialogFragment();
170 final Bundle args = new Bundle();
171 args.putCharSequence(Intent.EXTRA_TEXT, message);
172 f.setArguments(args);
173 f.setTargetFragment(CustomListPreferenceDialogFragment.this, 0);
174 final FragmentTransaction ft = getFragmentManager().beginTransaction();
175 ft.add(f, getTag() + "-Confirm");
176 ft.commitAllowingStateLoss();
177 } else {
178 onItemConfirmed();
179 }
180 }
181
182 /**
183 * Called when user has made a concrete item choice and we've fully
184 * confirmed they want to move forward (if we took a detour above).
185 */
186 protected void onItemConfirmed() {
187 onClick(getDialog(), DialogInterface.BUTTON_POSITIVE);
188 getDialog().dismiss();
189 }
190
Jason Monk39b46742015-09-10 15:52:51 -0400191 @Override
192 public void onDialogClosed(boolean positiveResult) {
193 getCustomizablePreference().onDialogClosed(positiveResult);
Jason Monk9cbf3252015-12-14 16:39:45 -0500194 final ListPreference preference = getCustomizablePreference();
Jeff Sharkey4a8136b2016-07-27 12:53:34 -0600195 final String value = getValue();
196 if (positiveResult && value != null) {
Jason Monk9cbf3252015-12-14 16:39:45 -0500197 if (preference.callChangeListener(value)) {
198 preference.setValue(value);
199 }
200 }
Jason Monk39b46742015-09-10 15:52:51 -0400201 }
202 }
Jeff Sharkey4a8136b2016-07-27 12:53:34 -0600203
Fan Zhangac5e5932016-08-24 18:13:33 -0700204 public static class ConfirmDialogFragment extends InstrumentedDialogFragment {
Jeff Sharkey4a8136b2016-07-27 12:53:34 -0600205 @Override
206 public Dialog onCreateDialog(Bundle savedInstanceState) {
Fan Zhangfb5bc062018-07-13 14:21:15 -0700207 return new Builder(getActivity())
Jeff Sharkey4a8136b2016-07-27 12:53:34 -0600208 .setMessage(getArguments().getCharSequence(Intent.EXTRA_TEXT))
209 .setPositiveButton(android.R.string.ok, new OnClickListener() {
210 @Override
211 public void onClick(DialogInterface dialog, int which) {
212 final Fragment f = getTargetFragment();
213 if (f != null) {
214 ((CustomListPreferenceDialogFragment) f).onItemConfirmed();
215 }
216 }
217 })
218 .setNegativeButton(android.R.string.cancel, null)
219 .create();
220 }
Fan Zhangac5e5932016-08-24 18:13:33 -0700221
222 @Override
223 public int getMetricsCategory() {
Fan Zhang31b21002019-01-16 13:49:47 -0800224 return SettingsEnums.DIALOG_CUSTOM_LIST_CONFIRMATION;
Fan Zhangac5e5932016-08-24 18:13:33 -0700225 }
Jeff Sharkey4a8136b2016-07-27 12:53:34 -0600226 }
Jason Monk39b46742015-09-10 15:52:51 -0400227}