`
lyunabc
  • 浏览: 561457 次
  • 性别: Icon_minigender_2
社区版块
存档分类
最新评论

Android ApiDemos示例解析(35):App->Preferences->Advanced preferences

 
阅读更多

前篇文章Android ApiDemo示例解析(31):App->Preferences->Launching preferences 中用到了Advanced preferences 中定义的AdvancedPreferences。

本篇具体介绍AdvancedPreferences, 这个例子称为Advanced ,是因为它涉及到了自定义Preference, 并在一个工作线程中刷新某个Preference的值。

Preference 为显示在PreferenceActivity (一般以列表显示)在某个偏好的基类。有点类似于显示在Activity中的某个View。Preference 实际存取的是对应在Shared Preferences中一项,而Preference定义的key也就是用来访问Shared Preferences的key值。

和View一样可以自定义View,在Android中也可以自定义Preference,用来显示管理应用自定义的程序偏好。本例 MyPreference 自定义一个Preference 用来存储用户点击该Preference的次数,类型为整数,初始值定义为100。它在advanced_preferences.xml 对应的定义如下:

<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″ />

Preference 定义了很多属性,比如Default Value, dependency, enabled, icon ,key 等等都有对应的方法来操作。并且提供了两个Listener:PreferenceChangeListener, PreferenceClickListener ,允许应用程序响应Preference值变化事件,或是用户点击Preference事件。

这里按照MyPreference 代码顺序说明一下如何自定义一个Preference。

1. 派生于 Preference基类。

public class MyPreference extends Preference


2. 和自定义View类似可以为自定义Preference 自定义Layout。 MyPreference 使用R.layout.preference_widget_mypreference ,定义很简单只有一个TextView ,其id为mypreference_widget。 一般在构造函数中使用setWidgetLayoutResource为Preference派生类设置Layout资源。

// This is the constructor called by the inflater
public MyPreference(Context context, AttributeSet attrs) {
 super(context, attrs);
 
 setWidgetLayoutResource(R.layout.preference_widget_mypreference);
}


3. 如有需要为自定义的Layout中的View 设置属性,可以在onBindView(View view)中完成。下面代码为TextView设置值为mClickCounter。

@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));
 }
 }


4. 如果为该自定义Preference 在XML定义了初值,比如 MyPreference的初值android:defaultValue=”100″,我们想在代码中使用这个初值来初始化变量mClickCounter 。mClickCounter 类型为整数,这个变量就是用来保存用户的按键次数的。

@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);
 }
}


5 重载 onSaveInstanceState,onRestoreInstanceState ,这两个方法是用来临时保存或是恢复一些变量值。在Preference 调用persistInt,persistBoolean, persistString等之前,preference 对应的值还没有被保存在或是更新在Shared preferences 中,如果这时用户旋转屏幕,则造成Activity重新创建,我们需要在屏幕旋转时用户选择项会保留,可以使用onSaveInstanceState,onRestoreInstanceState来保持一些临时数据。

@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为BaseSavedState的子类,这里不详细介绍了,而BaseSavedState实现了Parcelable接口,借用Windows平台上的Serialable,其功能和其它平台上序列化功能类似。

6. MyPreference响应Click事件,并将按键次数存入Shared Preferences 中。

@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();
}


Preference使用persistBoolean, persistFloat ,persistInt, persistLong ,persisitString 向Shared Preferences中存储数据,因为mClickCounter为整数,所以使用persistInt。 notifyChanged用于通知UI有数据变化。callChangeListener 将会调用注册过的Preference.OnPreferenceChangeListener 以通知Preference有变化。

再来看看AdvancedPreferences,代码不是很长,如下:

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();
 }
 }
 
}


它实现了OnSharedPreferenceChangeListener,因此可以用来监听MyPreference的变化。

Handler ,由于程序中需要从工作线程中更新Preference的值,而Preference为UI,不可以从工作线程中直接更新UI,Handler允许工作线程来更新UI,后续有详细介绍。本例每隔1秒将Haunted preference 值变化一次(选中->不选->选中->不选 ..)

registerOnSharedPreferenceChangeListener,unregisterOnSharedPreferenceChangeListener用来为SharedPreferences 注册一个总的Preference 变化事件处理代码。本例中MyPreference变化时在屏幕上显示当前按键的次数:

分享到:
评论

相关推荐

    Android ApiDemos示例解析(26):App->Notification->IncomingMessage

    本文将深入解析`ApiDemos`中的一个特定示例——`App-&gt;Notification-&gt;IncomingMessage`,帮助开发者更好地理解和应用Android的通知功能。 通知(Notification)是Android系统中一种关键的用户界面元素,它在状态栏中...

    android API-DEMOS中文解析文档

    #### 2.35 App-&gt;Preferences-&gt;Advancedpreferences 这部分内容涉及了更高级的偏好设置管理技巧。 #### 2.36 App-&gt;Search-&gt;InvokeSearch 这部分内容介绍了如何调用搜索功能。 #### 2.37 App-&gt;Search-&gt;...

    android apidemos示例解析

    ### Android ApiDemos示例解析 #### 概述 Android ApiDemos是一个官方提供的示例应用程序集合,旨在帮助开发者理解并掌握Android SDK的各种API用法。通过这些示例,开发者可以学习到如何在实际项目中应用不同的...

    Android ApiDemos4.4 示例解析

    最新版ApiDemos Android SDK 中带有很多例子,其中ApiDemo 详细介绍了Android 平台主要API,分成了 · App · Content · Graphics · Media · OS · Text · Views 几个大类,每个大类又分为几个小类,...

    最新Android apidemos

    《深入探索Android API Demos:最新实践与技术解析》 Android API Demos是Google官方提供的一款用于展示Android SDK中各种API功能和用法的应用程序,它涵盖了从基础控件到高级特性的全方位示例,是开发者学习...

    ApiDemos示例源码

    《ApiDemos示例源码解析》 ApiDemos是Android平台提供的一款示例应用,它包含了Android SDK中的各种API功能展示,对于开发者来说,这是一个非常宝贵的资源库,可以帮助我们深入理解和学习Android系统的API用法。...

    Android6.0 Api Demos

    Android 6.0 API Demos 是一个官方提供的示例代码集合,它展示了Android 6.0 (Marshmallow) SDK中的各种API功能和用法。这些示例旨在帮助开发者更好地理解和学习如何在实际应用中使用Android的新特性和API。下面将...

    Android ApiDemos apk

    Android ApiDemos apk是Android开发者们熟悉的一个示例程序,它包含了Android SDK中的各种API功能演示,为开发者提供了丰富的学习资源。这个应用程序旨在帮助开发者更好地理解和掌握Android平台的各种功能和特性,...

    android ApiDemos不报错版本

    Android ApiDemos是Android平台上的一个官方示例项目,它为开发者提供了丰富的API演示,涵盖了Android系统中的各种控件和功能,是学习和理解Android开发的宝贵资源。这个不报错版本确保了无论是通过虚拟机还是真机...

    android1.6 apiDemos

    《Android 1.6 API Demos深度解析》 在Android开发的世界中,API Demos是一个不可或缺的学习资源,它为开发者提供了丰富的示例代码,帮助理解并掌握Android API的各种功能。本篇文章将深入探讨"android1.6 apiDemos...

    Android ApiDemos

    `Android ApiDemos` 是Android系统提供的一款官方示例程序,它集合了Android SDK中的各种API用法,是开发者学习和理解Android开发的关键资源。这个项目旨在通过实例代码来演示Android API的各种功能和组件,帮助...

    android ApiDemos

    Android API Demos是一款由谷歌官方提供的开源项目,它包含了大量Android SDK中的API示例代码,旨在帮助开发者更好地理解和学习如何在实际应用中使用Android的各种功能和API。该项目覆盖了从基础组件到高级特性的全...

    Android ApiDemos不报错版本,eclipse可用

    ApiDemos是Android官方提供的一款示例应用,它包含了Android SDK中的各种API功能演示,帮助开发者了解和学习Android系统提供的各种API接口和功能。这个"Android ApiDemos不报错版本"是针对eclipse开发环境优化过的,...

    android的ApiDemos

    API Demos 是 Google 为了 Android 开发者所提供的一个 Android API 合集,其中包含了很多的 API 范例,同时遵循了良好的代码规范,是一个值得开发者研究和学习的典型。android的ApiDemos,需要解压缩后使用。

    Android ApiDemos2.1

    `Android ApiDemos 2.1` 是Android SDK中一个非常重要的示例程序,它包含了Android API的各种功能和组件的演示,是开发者学习和理解Android系统API的重要资源。这个版本对应的是Android 2.1(API级别7)的时代,虽然...

    Android2.2 ApiDemos

    《Android 2.2 ApiDemos深度解析》 在Android开发领域,ApiDemos是一个非常重要的参考资料,它是由Google官方提供的一个示例程序,包含了Android SDK中的各种API功能的演示。这个项目,针对的是Android 2.2(API...

    android apidemos

    Android API Demos是Android开发者平台提供的一款强大的学习工具,它包含了大量的示例代码,覆盖了Android系统API的各种功能和组件,对于初学者和经验丰富的开发者来说,都是深入理解Android系统及其API的重要资源。...

    android api19 ApiDemos

    在Android开发领域,API Demos是一个非常重要的学习资源,它包含了Android SDK中的各种API示例代码,帮助开发者深入理解和掌握Android平台的功能特性。本文将针对API Level 19(KitKat版本)的ApiDemos进行详细解析...

Global site tag (gtag.js) - Google Analytics