Prefercence 观察来看设计思想应该是简化设置的UI的界面布局所用。
主题是 PreFerenceActivity
1:xml
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <PreferenceCategory android:title="@string/inline_preferences"> <CheckBoxPreference android:key="checkbox_preference" android:title="@string/title_toggle_preference" android:summary="@string/summary_toggle_preference" /> </PreferenceCategory> <PreferenceCategory android:title="@string/dialog_based_preferences"> <EditTextPreference android:key="edittext_preference" android:title="@string/title_edittext_preference" android:summary="@string/summary_edittext_preference" android:dialogTitle="@string/dialog_title_edittext_preference" /> <ListPreference android:key="list_preference" android:title="@string/title_list_preference" android:summary="@string/summary_list_preference" android:entries="@array/entries_list_preference" android:entryValues="@array/entryvalues_list_preference" android:dialogTitle="@string/dialog_title_list_preference" /> </PreferenceCategory> <PreferenceCategory android:title="@string/launch_preferences"> <!-- This PreferenceScreen tag serves as a screen break (similar to page break in word processing). Like for other preference types, we assign a key here so it is able to save and restore its instance state. --> <PreferenceScreen android:key="screen_preference" android:title="@string/title_screen_preference" android:summary="@string/summary_screen_preference"> <!-- You can place more preferences here that will be shown on the next screen. --> <CheckBoxPreference android:key="next_screen_checkbox_preference" android:title="@string/title_next_screen_toggle_preference" android:summary="@string/summary_next_screen_toggle_preference" /> </PreferenceScreen> <PreferenceScreen android:title="@string/title_intent_preference" android:summary="@string/summary_intent_preference"> <intent android:action="android.intent.action.VIEW" android:data="http://www.android.com" /> </PreferenceScreen> </PreferenceCategory> <PreferenceCategory android:title="@string/preference_attributes"> <CheckBoxPreference android:key="parent_checkbox_preference" android:title="@string/title_parent_preference" android:summary="@string/summary_parent_preference" /> <!-- The visual style of a child is defined by this styled theme attribute. --> <CheckBoxPreference android:key="child_checkbox_preference" android:dependency="parent_checkbox_preference" android:layout="?android:attr/preferenceLayoutChild" android:title="@string/title_child_preference" android:summary="@string/summary_child_preference" /> </PreferenceCategory> </PreferenceScreen>
Code实现:
private PreferenceScreen createPreferenceHierarchy() { // Root PreferenceScreen root = getPreferenceManager().createPreferenceScreen(this); // Inline preferences PreferenceCategory inlinePrefCat = new PreferenceCategory(this); inlinePrefCat.setTitle(R.string.inline_preferences); root.addPreference(inlinePrefCat); // Toggle preference CheckBoxPreference togglePref = new CheckBoxPreference(this); togglePref.setKey("toggle_preference"); togglePref.setTitle(R.string.title_toggle_preference); togglePref.setSummary(R.string.summary_toggle_preference); inlinePrefCat.addPreference(togglePref); // Dialog based preferences PreferenceCategory dialogBasedPrefCat = new PreferenceCategory(this); dialogBasedPrefCat.setTitle(R.string.dialog_based_preferences); root.addPreference(dialogBasedPrefCat); // Edit text preference EditTextPreference editTextPref = new EditTextPreference(this); editTextPref.setDialogTitle(R.string.dialog_title_edittext_preference); editTextPref.setKey("edittext_preference"); editTextPref.setTitle(R.string.title_edittext_preference); editTextPref.setSummary(R.string.summary_edittext_preference); dialogBasedPrefCat.addPreference(editTextPref); // List preference ListPreference listPref = new ListPreference(this); listPref.setEntries(R.array.entries_list_preference); listPref.setEntryValues(R.array.entryvalues_list_preference); listPref.setDialogTitle(R.string.dialog_title_list_preference); listPref.setKey("list_preference"); listPref.setTitle(R.string.title_list_preference); listPref.setSummary(R.string.summary_list_preference); dialogBasedPrefCat.addPreference(listPref); // Launch preferences PreferenceCategory launchPrefCat = new PreferenceCategory(this); launchPrefCat.setTitle(R.string.launch_preferences); root.addPreference(launchPrefCat); /* * The Preferences screenPref serves as a screen break (similar to page * break in word processing). Like for other preference types, we assign * a key here so that it is able to save and restore its instance state. */ // Screen preference PreferenceScreen screenPref = getPreferenceManager().createPreferenceScreen(this); screenPref.setKey("screen_preference"); screenPref.setTitle(R.string.title_screen_preference); screenPref.setSummary(R.string.summary_screen_preference); launchPrefCat.addPreference(screenPref); /* * You can add more preferences to screenPref that will be shown on the * next screen. */ // Example of next screen toggle preference CheckBoxPreference nextScreenCheckBoxPref = new CheckBoxPreference(this); nextScreenCheckBoxPref.setKey("next_screen_toggle_preference"); nextScreenCheckBoxPref.setTitle(R.string.title_next_screen_toggle_preference); nextScreenCheckBoxPref.setSummary(R.string.summary_next_screen_toggle_preference); screenPref.addPreference(nextScreenCheckBoxPref); // Intent preference PreferenceScreen intentPref = getPreferenceManager().createPreferenceScreen(this); intentPref.setIntent(new Intent().setAction(Intent.ACTION_VIEW) .setData(Uri.parse("http://www.android.com"))); intentPref.setTitle(R.string.title_intent_preference); intentPref.setSummary(R.string.summary_intent_preference); launchPrefCat.addPreference(intentPref); // Preference attributes PreferenceCategory prefAttrsCat = new PreferenceCategory(this); prefAttrsCat.setTitle(R.string.preference_attributes); root.addPreference(prefAttrsCat); // Visual parent toggle preference CheckBoxPreference parentCheckBoxPref = new CheckBoxPreference(this); parentCheckBoxPref.setTitle(R.string.title_parent_preference); parentCheckBoxPref.setSummary(R.string.summary_parent_preference); parentCheckBoxPref.setKey("test"); prefAttrsCat.addPreference(parentCheckBoxPref); // Visual child toggle preference // See res/values/attrs.xml for the <declare-styleable> that defines // TogglePrefAttrs. //代码有个问题就是父子的依赖处理没有实现,如何实现本人 //用setDependent()没有测试出来,xml的依赖是对的。 TypedArray a = obtainStyledAttributes(R.styleable.TogglePrefAttrs); CheckBoxPreference childCheckBoxPref = new CheckBoxPreference(this); childCheckBoxPref.setTitle(R.string.title_child_preference); childCheckBoxPref.setSummary(R.string.summary_child_preference); childCheckBoxPref.setDisableDependentsState(true); childCheckBoxPref.setLayoutResource( a.getResourceId(R.styleable.TogglePrefAttrs_android_preferenceLayoutChild, 0)); prefAttrsCat.addPreference(childCheckBoxPref); a.recycle(); return root;
亦可以自定义PreFerecnce控件 MyPreference
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); } @Override protected void onBindView(View 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); // 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() { /* * 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]; } }; } }
<?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2006 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <!-- Custom preference type using a text view. --> <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" />
使用:
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <!-- My custom preference type. This just replaces the actual widget portion of the preference, if the whole preference wanted to be replaced we would use the layout attribute instead of the widgetLayout attribute. --> <com.example.android.apis.app.MyPreference 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>
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); } @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(); } } }
可以在Activity 主UI 线程中 使用preference xml 的值
1:先在主UI中定义
/*
* If this were my app's main activity, I would load the default values
* so they're set even if the user does not go into the preferences
* screen. Another good place to call this method would be from a
* subclass of Application, so your default values would be loaded
* regardless of entry into your application (for example, a service or
* activity).
*/
PreferenceManager.setDefaultValues(this, R.xml.advanced_preferences, false);
2: 使用
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
final int counter = sharedPref.getInt(AdvancedPreferences.KEY_MY_PREFERENCE, 0);