1/* 2 * Copyright (C) 2007 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 android.preference; 18 19 20import android.content.Context; 21import android.content.SharedPreferences; 22import android.content.res.TypedArray; 23import android.os.Parcel; 24import android.os.Parcelable; 25import android.text.TextUtils; 26import android.util.AttributeSet; 27import android.view.View; 28import android.view.ViewGroup; 29import android.view.ViewParent; 30import android.widget.EditText; 31 32/** 33 * A {@link Preference} that allows for string 34 * input. 35 * <p> 36 * It is a subclass of {@link DialogPreference} and shows the {@link EditText} 37 * in a dialog. This {@link EditText} can be modified either programmatically 38 * via {@link #getEditText()}, or through XML by setting any EditText 39 * attributes on the EditTextPreference. 40 * <p> 41 * This preference will store a string into the SharedPreferences. 42 * <p> 43 * See {@link android.R.styleable#EditText EditText Attributes}. 44 */ 45public class EditTextPreference extends DialogPreference { 46 /** 47 * The edit text shown in the dialog. 48 */ 49 private EditText mEditText; 50 51 private String mText; 52 53 public EditTextPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 54 super(context, attrs, defStyleAttr, defStyleRes); 55 56 mEditText = new EditText(context, attrs); 57 58 // Give it an ID so it can be saved/restored 59 mEditText.setId(com.android.internal.R.id.edit); 60 61 /* 62 * The preference framework and view framework both have an 'enabled' 63 * attribute. Most likely, the 'enabled' specified in this XML is for 64 * the preference framework, but it was also given to the view framework. 65 * We reset the enabled state. 66 */ 67 mEditText.setEnabled(true); 68 } 69 70 public EditTextPreference(Context context, AttributeSet attrs, int defStyleAttr) { 71 this(context, attrs, defStyleAttr, 0); 72 } 73 74 public EditTextPreference(Context context, AttributeSet attrs) { 75 this(context, attrs, com.android.internal.R.attr.editTextPreferenceStyle); 76 } 77 78 public EditTextPreference(Context context) { 79 this(context, null); 80 } 81 82 /** 83 * Saves the text to the {@link SharedPreferences}. 84 * 85 * @param text The text to save 86 */ 87 public void setText(String text) { 88 final boolean wasBlocking = shouldDisableDependents(); 89 90 mText = text; 91 92 persistString(text); 93 94 final boolean isBlocking = shouldDisableDependents(); 95 if (isBlocking != wasBlocking) { 96 notifyDependencyChange(isBlocking); 97 } 98 } 99 100 /** 101 * Gets the text from the {@link SharedPreferences}. 102 * 103 * @return The current preference value. 104 */ 105 public String getText() { 106 return mText; 107 } 108 109 @Override 110 protected void onBindDialogView(View view) { 111 super.onBindDialogView(view); 112 113 EditText editText = mEditText; 114 editText.setText(getText()); 115 116 ViewParent oldParent = editText.getParent(); 117 if (oldParent != view) { 118 if (oldParent != null) { 119 ((ViewGroup) oldParent).removeView(editText); 120 } 121 onAddEditTextToDialogView(view, editText); 122 } 123 } 124 125 /** 126 * Adds the EditText widget of this preference to the dialog's view. 127 * 128 * @param dialogView The dialog view. 129 */ 130 protected void onAddEditTextToDialogView(View dialogView, EditText editText) { 131 ViewGroup container = (ViewGroup) dialogView 132 .findViewById(com.android.internal.R.id.edittext_container); 133 if (container != null) { 134 container.addView(editText, ViewGroup.LayoutParams.MATCH_PARENT, 135 ViewGroup.LayoutParams.WRAP_CONTENT); 136 } 137 } 138 139 @Override 140 protected void onDialogClosed(boolean positiveResult) { 141 super.onDialogClosed(positiveResult); 142 143 if (positiveResult) { 144 String value = mEditText.getText().toString(); 145 if (callChangeListener(value)) { 146 setText(value); 147 } 148 } 149 } 150 151 @Override 152 protected Object onGetDefaultValue(TypedArray a, int index) { 153 return a.getString(index); 154 } 155 156 @Override 157 protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { 158 setText(restoreValue ? getPersistedString(mText) : (String) defaultValue); 159 } 160 161 @Override 162 public boolean shouldDisableDependents() { 163 return TextUtils.isEmpty(mText) || super.shouldDisableDependents(); 164 } 165 166 /** 167 * Returns the {@link EditText} widget that will be shown in the dialog. 168 * 169 * @return The {@link EditText} widget that will be shown in the dialog. 170 */ 171 public EditText getEditText() { 172 return mEditText; 173 } 174 175 /** @hide */ 176 @Override 177 protected boolean needInputMethod() { 178 // We want the input method to show, if possible, when dialog is displayed 179 return true; 180 } 181 182 @Override 183 protected Parcelable onSaveInstanceState() { 184 final Parcelable superState = super.onSaveInstanceState(); 185 if (isPersistent()) { 186 // No need to save instance state since it's persistent 187 return superState; 188 } 189 190 final SavedState myState = new SavedState(superState); 191 myState.text = getText(); 192 return myState; 193 } 194 195 @Override 196 protected void onRestoreInstanceState(Parcelable state) { 197 if (state == null || !state.getClass().equals(SavedState.class)) { 198 // Didn't save state for us in onSaveInstanceState 199 super.onRestoreInstanceState(state); 200 return; 201 } 202 203 SavedState myState = (SavedState) state; 204 super.onRestoreInstanceState(myState.getSuperState()); 205 setText(myState.text); 206 } 207 208 private static class SavedState extends BaseSavedState { 209 String text; 210 211 public SavedState(Parcel source) { 212 super(source); 213 text = source.readString(); 214 } 215 216 @Override 217 public void writeToParcel(Parcel dest, int flags) { 218 super.writeToParcel(dest, flags); 219 dest.writeString(text); 220 } 221 222 public SavedState(Parcelable superState) { 223 super(superState); 224 } 225 226 public static final Parcelable.Creator<SavedState> CREATOR = 227 new Parcelable.Creator<SavedState>() { 228 public SavedState createFromParcel(Parcel in) { 229 return new SavedState(in); 230 } 231 232 public SavedState[] newArray(int size) { 233 return new SavedState[size]; 234 } 235 }; 236 } 237 238} 239