mobile/android/base/preferences/CustomListPreference.java

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

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

mercurial