mobile/android/base/preferences/CustomListPreference.java

branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
equal deleted inserted replaced
-1:000000000000 0:ac509e86e389
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 package org.mozilla.gecko.preferences;
6
7 import org.mozilla.gecko.R;
8
9 import android.app.AlertDialog;
10 import android.content.Context;
11 import android.content.DialogInterface;
12 import android.content.res.Resources;
13 import android.preference.Preference;
14 import android.view.View;
15 import android.widget.TextView;
16
17 /**
18 * Represents an element in a <code>CustomListCategory</code> preference menu.
19 * This preference con display a dialog when clicked, and also supports
20 * being set as a default item within the preference list category.
21 */
22
23 public abstract class CustomListPreference extends Preference implements View.OnLongClickListener {
24 protected String LOGTAG = "CustomListPreference";
25
26 // Indices of the buttons of the Dialog.
27 public static final int INDEX_SET_DEFAULT_BUTTON = 0;
28
29 // Dialog item labels.
30 private String[] mDialogItems;
31
32 // Dialog displayed when this element is tapped.
33 protected AlertDialog mDialog;
34
35 // Cache label to avoid repeated use of the resource system.
36 protected final String LABEL_IS_DEFAULT;
37 protected final String LABEL_SET_AS_DEFAULT;
38 protected final String LABEL_REMOVE;
39
40 protected boolean mIsDefault;
41
42 // Enclosing parent category that contains this preference.
43 protected final CustomListCategory mParentCategory;
44
45 /**
46 * Create a preference object to represent a list preference that is attached to
47 * a category.
48 *
49 * @param context The activity context we operate under.
50 * @param parentCategory The PreferenceCategory this object exists within.
51 */
52 public CustomListPreference(Context context, CustomListCategory parentCategory) {
53 super(context);
54
55 mParentCategory = parentCategory;
56 setLayoutResource(getPreferenceLayoutResource());
57
58 setOnPreferenceClickListener(new OnPreferenceClickListener() {
59 @Override
60 public boolean onPreferenceClick(Preference preference) {
61 CustomListPreference sPref = (CustomListPreference) preference;
62 sPref.showDialog();
63 return true;
64 }
65 });
66
67 Resources res = getContext().getResources();
68
69 // Fetch these strings now, instead of every time we ever want to relabel a button.
70 LABEL_IS_DEFAULT = res.getString(R.string.pref_default);
71 LABEL_SET_AS_DEFAULT = res.getString(R.string.pref_dialog_set_default);
72 LABEL_REMOVE = res.getString(R.string.pref_dialog_remove);
73 }
74
75 /**
76 * Returns the Android resource id for the layout.
77 */
78 protected abstract int getPreferenceLayoutResource();
79
80 /**
81 * Set whether this object's UI should display this as the default item.
82 * Note: This must be called from the UI thread because it touches the view hierarchy.
83 *
84 * To ensure proper ordering, this method should only be called after this Preference
85 * is added to the PreferenceCategory.
86 *
87 * @param isDefault Flag indicating if this represents the default list item.
88 */
89 public void setIsDefault(boolean isDefault) {
90 mIsDefault = isDefault;
91 if (isDefault) {
92 setOrder(0);
93 setSummary(LABEL_IS_DEFAULT);
94 } else {
95 setOrder(1);
96 setSummary("");
97 }
98 }
99
100 private String[] getCachedDialogItems() {
101 if (mDialogItems == null) {
102 mDialogItems = createDialogItems();
103 }
104 return mDialogItems;
105 }
106
107 /**
108 * Returns the strings to be displayed in the dialog.
109 */
110 abstract protected String[] createDialogItems();
111
112 /**
113 * Display a dialog for this preference, when the preference is clicked.
114 */
115 public void showDialog() {
116 final AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
117 builder.setTitle(getTitle().toString());
118 builder.setItems(getCachedDialogItems(), new DialogInterface.OnClickListener() {
119 // Forward relevant events to the container class for handling.
120 @Override
121 public void onClick(DialogInterface dialog, int indexClicked) {
122 hideDialog();
123 onDialogIndexClicked(indexClicked);
124 }
125 });
126
127 configureDialogBuilder(builder);
128
129 // We have to construct the dialog itself on the UI thread.
130 mDialog = builder.create();
131 mDialog.setOnShowListener(new DialogInterface.OnShowListener() {
132 // Called when the dialog is shown (so we're finally able to manipulate button enabledness).
133 @Override
134 public void onShow(DialogInterface dialog) {
135 configureShownDialog();
136 }
137 });
138 mDialog.show();
139 }
140
141 /**
142 * (Optional) Configure the AlertDialog builder.
143 */
144 protected void configureDialogBuilder(AlertDialog.Builder builder) {
145 return;
146 }
147
148 abstract protected void onDialogIndexClicked(int index);
149
150 /**
151 * Disables buttons in the shown AlertDialog as required. The button elements are not created
152 * until after show is called, so this method has to be called from the onShowListener above.
153 * @see this.showDialog
154 */
155 protected void configureShownDialog() {
156 // If this is already the default list item, disable the button for setting this as the default.
157 final TextView defaultButton = (TextView) mDialog.getListView().getChildAt(INDEX_SET_DEFAULT_BUTTON);
158 if (mIsDefault) {
159 defaultButton.setEnabled(false);
160
161 // Failure to unregister this listener leads to tapping the button dismissing the dialog
162 // without doing anything.
163 defaultButton.setOnClickListener(null);
164 }
165 }
166
167 /**
168 * Hide the dialog we previously created, if any.
169 */
170 public void hideDialog() {
171 if (mDialog != null && mDialog.isShowing()) {
172 mDialog.dismiss();
173 }
174 }
175
176 @Override
177 public boolean onLongClick(View view) {
178 // Show the preference dialog on long-press.
179 showDialog();
180 return true;
181 }
182 }

mercurial