Api-Demo Advanced preference分析

来源:互联网 发布:淘宝网纸箱 编辑:程序博客网 时间:2024/05/18 15:07

该Demo的效果图如下所示,点击MyPreference,数字会增加。而CheckBoxPreference则自动在Check和UnCheck切换:

advanced_preferences.xml

<PreferenceScreen        xmlns:android="http://schemas.android.com/apk/res/android">    <com.example.android.apis.preference.MyPreference//自定义Preference的写法            android:key="my_preference"            android:title="@string/title_my_preference"            android:summary="@string/summary_my_preference"            android:defaultValue="100" />    <CheckBoxPreference            android:key="advanced_checkbox_preference"            android:title="@string/title_advanced_toggle_preference"            android:summaryOn="@string/summary_on_advanced_toggle_preference"             android:summaryOff="@string/summary_off_advanced_toggle_preference" /></PreferenceScreen>

AdvancedPreferences.java

package com.example.android.apis.preference;import com.example.android.apis.R;import android.content.SharedPreferences;import android.content.SharedPreferences.OnSharedPreferenceChangeListener;import android.os.Bundle;import android.os.Handler;import android.preference.PreferenceActivity;import android.preference.CheckBoxPreference;import android.widget.Toast;/** * Example that shows finding a preference from the hierarchy and a custom preference type. */public class AdvancedPreferences extends PreferenceActivity implements OnSharedPreferenceChangeListener {    public static final String KEY_MY_PREFERENCE = "my_preference";    public static final String KEY_ADVANCED_CHECKBOX_PREFERENCE = "advanced_checkbox_preference";    private CheckBoxPreference mCheckBoxPreference;    private Handler mHandler = new Handler();    /**     * This is a simple example of controlling a preference from code.     */    private Runnable mForceCheckBoxRunnable = new Runnable() {        public void run() {            if (mCheckBoxPreference != null) {                mCheckBoxPreference.setChecked(!mCheckBoxPreference.isChecked());            }            // Force toggle again in a second            mHandler.postDelayed(this, 1000);        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        // Load the XML preferences file        addPreferencesFromResource(R.xml.advanced_preferences);        // Get a reference to the checkbox preference        mCheckBoxPreference = (CheckBoxPreference)getPreferenceScreen().findPreference(                KEY_ADVANCED_CHECKBOX_PREFERENCE);    }    @Override    protected void onResume() {        super.onResume();        // Start the force toggle        mForceCheckBoxRunnable.run();        // Set up a listener whenever a key changes        getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);//监听器一般都定义有注册监听和注销监听这两个方法,究其原因1.规定监听器的作用时间2.起作用的是哪个监听器.    }    @Override    protected void onPause() {        super.onPause();        // Unregister the listener whenever a key changes        getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);        mHandler.removeCallbacks(mForceCheckBoxRunnable);    }    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {        // Let's do something when my counter preference value changes        if (key.equals(KEY_MY_PREFERENCE)) {            Toast.makeText(this, "Thanks! You increased my count to "                    + sharedPreferences.getInt(key, 0), Toast.LENGTH_SHORT).show();        }    }}

MyPreference.java

package com.example.android.apis.preference;import com.example.android.apis.R;import android.content.Context;import android.content.res.TypedArray;import android.os.Parcel;import android.os.Parcelable;import android.preference.Preference;import android.util.AttributeSet;import android.view.View;import android.widget.TextView;/** * This is an example of a custom preference type. The preference counts the * number of clicks it has received and stores/retrieves it from the storage. */public class MyPreference extends Preference {    private int mClickCounter;    // This is the constructor called by the inflater    public MyPreference(Context context, AttributeSet attrs) {        super(context, attrs);        setWidgetLayoutResource(R.layout.preference_widget_mypreference);//一开始很奇怪为什么自定义的Preference的layout样式和CheckBoxPreference等一样,看了源码才明白:Preference是有view视图的,因此它定义了自己的layout视图,源码中给出的layout为——com.android.internal.R.layout.preference,这个layout样式正是如图所示的样式,Preference API提供了layout属性供用户定义自己的layout样式,本篇并没有定义自己的layout,因此样式仍不变;同时在这个layout中有一个widget控件供用户自定义,本篇中自定义为了一个TextView,CheckBoxPreference中是一个CheckBox。    }    @Override    protected void onBindView(View view) {//Preference API提供了三个与UI视图相关的回调函数,第一个是onCreatView,查看源码可知这个函数填充layout和那个控件;第二个是onBindView,它用于绑定数据到layout中,比如summary和title等;第三个是getView,取出这个view视图。        super.onBindView(view);        // Set our custom views inside the layout        final TextView myTextView = (TextView) view.findViewById(R.id.mypreference_widget);        if (myTextView != null) {            myTextView.setText(String.valueOf(mClickCounter));        }    }    @Override    protected void onClick() {        int newValue = mClickCounter + 1;        // Give the client a chance to ignore this change if they deem it        // invalid        if (!callChangeListener(newValue)) {            // They don't want the value to be set            return;        }        // Increment counter        mClickCounter = newValue;        // Save to persistent storage (this method will make sure this        // preference should be persistent, along with other useful checks)        persistInt(mClickCounter);//永久保存数据到SharedPreference中,因为设置的很多东西是必须一直保存的,因此Preference中定义了很多“persist”的变量和方法。        // Data has changed, notify so UI can be refreshed!        notifyChanged();    }    @Override    protected Object onGetDefaultValue(TypedArray a, int index) {        // This preference type's value type is Integer, so we read the default        // value from the attributes as an Integer.        return a.getInteger(index, 0);    }    @Override    protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {        if (restoreValue) {            // Restore state            mClickCounter = getPersistedInt(mClickCounter);        } else {            // Set state            int value = (Integer) defaultValue;            mClickCounter = value;            persistInt(value);        }    }    @Override    protected Parcelable onSaveInstanceState() {//有了"persist"作长久保存,为什么还要有这个回调呢,原因就在于还没作保存到SharedPreference中,如果用户比如旋转屏幕,则参数必须重新加载,而onSaveInstanceState()和onRestoreInstanceState()两个函数就起到了短暂保存参数的作用。同时这里我们也可以借鉴到以后编写Activity和Fragment需要短暂保存的参数时考虑这两个方法。        /*         * Suppose a client uses this preference type without persisting. We         * must save the instance state so it is able to, for example, survive         * orientation changes.         */        final Parcelable superState = super.onSaveInstanceState();        if (isPersistent()) {            // No need to save instance state since it's persistent            return superState;        }        // Save the instance state        final SavedState myState = new SavedState(superState);        myState.clickCounter = mClickCounter;        return myState;    }    @Override    protected void onRestoreInstanceState(Parcelable state) {        if (!state.getClass().equals(SavedState.class)) {            // Didn't save state for us in onSaveInstanceState            super.onRestoreInstanceState(state);            return;        }        // Restore the instance state        SavedState myState = (SavedState) state;        super.onRestoreInstanceState(myState.getSuperState());        mClickCounter = myState.clickCounter;        notifyChanged();    }    /**     * SavedState, a subclass of {@link BaseSavedState}, will store the state     * of MyPreference, a subclass of Preference.     * <p>     * It is important to always call through to super methods.     */    private static class SavedState extends BaseSavedState {        int clickCounter;        public SavedState(Parcel source) {            super(source);            // Restore the click counter            clickCounter = source.readInt();        }        @Override        public void writeToParcel(Parcel dest, int flags) {            super.writeToParcel(dest, flags);            // Save the click counter            dest.writeInt(clickCounter);        }        public SavedState(Parcelable superState) {            super(superState);        }        public static final Parcelable.Creator<SavedState> CREATOR =                new Parcelable.Creator<SavedState>() {            public SavedState createFromParcel(Parcel in) {                return new SavedState(in);            }            public SavedState[] newArray(int size) {                return new SavedState[size];            }        };    }}
preference_widget_mypreference.xml

<TextView xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/mypreference_widget"     android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:layout_gravity="center_vertical"    android:layout_marginRight="6sp"    android:focusable="false"    android:clickable="false" />



原创粉丝点击