Home | History | Annotate | Download | only in preference
      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.content.Context;
     21 import android.content.SharedPreferences;
     22 import android.content.res.TypedArray;
     23 import android.os.Parcel;
     24 import android.os.Parcelable;
     25 import android.text.TextUtils;
     26 import android.util.AttributeSet;
     27 import android.view.View;
     28 import android.view.ViewGroup;
     29 import android.view.ViewParent;
     30 import 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  */
     45 public 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 defStyle) {
     54         super(context, attrs, defStyle);
     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) {
     71         this(context, attrs, com.android.internal.R.attr.editTextPreferenceStyle);
     72     }
     73 
     74     public EditTextPreference(Context context) {
     75         this(context, null);
     76     }
     77 
     78     /**
     79      * Saves the text to the {@link SharedPreferences}.
     80      *
     81      * @param text The text to save
     82      */
     83     public void setText(String text) {
     84         final boolean wasBlocking = shouldDisableDependents();
     85 
     86         mText = text;
     87 
     88         persistString(text);
     89 
     90         final boolean isBlocking = shouldDisableDependents();
     91         if (isBlocking != wasBlocking) {
     92             notifyDependencyChange(isBlocking);
     93         }
     94     }
     95 
     96     /**
     97      * Gets the text from the {@link SharedPreferences}.
     98      *
     99      * @return The current preference value.
    100      */
    101     public String getText() {
    102         return mText;
    103     }
    104 
    105     @Override
    106     protected void onBindDialogView(View view) {
    107         super.onBindDialogView(view);
    108 
    109         EditText editText = mEditText;
    110         editText.setText(getText());
    111 
    112         ViewParent oldParent = editText.getParent();
    113         if (oldParent != view) {
    114             if (oldParent != null) {
    115                 ((ViewGroup) oldParent).removeView(editText);
    116             }
    117             onAddEditTextToDialogView(view, editText);
    118         }
    119     }
    120 
    121     /**
    122      * Adds the EditText widget of this preference to the dialog's view.
    123      *
    124      * @param dialogView The dialog view.
    125      */
    126     protected void onAddEditTextToDialogView(View dialogView, EditText editText) {
    127         ViewGroup container = (ViewGroup) dialogView
    128                 .findViewById(com.android.internal.R.id.edittext_container);
    129         if (container != null) {
    130             container.addView(editText, ViewGroup.LayoutParams.MATCH_PARENT,
    131                     ViewGroup.LayoutParams.WRAP_CONTENT);
    132         }
    133     }
    134 
    135     @Override
    136     protected void onDialogClosed(boolean positiveResult) {
    137         super.onDialogClosed(positiveResult);
    138 
    139         if (positiveResult) {
    140             String value = mEditText.getText().toString();
    141             if (callChangeListener(value)) {
    142                 setText(value);
    143             }
    144         }
    145     }
    146 
    147     @Override
    148     protected Object onGetDefaultValue(TypedArray a, int index) {
    149         return a.getString(index);
    150     }
    151 
    152     @Override
    153     protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
    154         setText(restoreValue ? getPersistedString(mText) : (String) defaultValue);
    155     }
    156 
    157     @Override
    158     public boolean shouldDisableDependents() {
    159         return TextUtils.isEmpty(mText) || super.shouldDisableDependents();
    160     }
    161 
    162     /**
    163      * Returns the {@link EditText} widget that will be shown in the dialog.
    164      *
    165      * @return The {@link EditText} widget that will be shown in the dialog.
    166      */
    167     public EditText getEditText() {
    168         return mEditText;
    169     }
    170 
    171     /** @hide */
    172     @Override
    173     protected boolean needInputMethod() {
    174         // We want the input method to show, if possible, when dialog is displayed
    175         return true;
    176     }
    177 
    178     @Override
    179     protected Parcelable onSaveInstanceState() {
    180         final Parcelable superState = super.onSaveInstanceState();
    181         if (isPersistent()) {
    182             // No need to save instance state since it's persistent
    183             return superState;
    184         }
    185 
    186         final SavedState myState = new SavedState(superState);
    187         myState.text = getText();
    188         return myState;
    189     }
    190 
    191     @Override
    192     protected void onRestoreInstanceState(Parcelable state) {
    193         if (state == null || !state.getClass().equals(SavedState.class)) {
    194             // Didn't save state for us in onSaveInstanceState
    195             super.onRestoreInstanceState(state);
    196             return;
    197         }
    198 
    199         SavedState myState = (SavedState) state;
    200         super.onRestoreInstanceState(myState.getSuperState());
    201         setText(myState.text);
    202     }
    203 
    204     private static class SavedState extends BaseSavedState {
    205         String text;
    206 
    207         public SavedState(Parcel source) {
    208             super(source);
    209             text = source.readString();
    210         }
    211 
    212         @Override
    213         public void writeToParcel(Parcel dest, int flags) {
    214             super.writeToParcel(dest, flags);
    215             dest.writeString(text);
    216         }
    217 
    218         public SavedState(Parcelable superState) {
    219             super(superState);
    220         }
    221 
    222         public static final Parcelable.Creator<SavedState> CREATOR =
    223                 new Parcelable.Creator<SavedState>() {
    224             public SavedState createFromParcel(Parcel in) {
    225                 return new SavedState(in);
    226             }
    227 
    228             public SavedState[] newArray(int size) {
    229                 return new SavedState[size];
    230             }
    231         };
    232     }
    233 
    234 }
    235