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