Preferece(1)



在Android系统中,当我们点击Menu按钮时,则会弹出Menu的菜单选项,其中一项是设置选项,点击了设置选项后,则会弹出系统的设置 Activity界面,这些设置功能是如何实现的呢?Android系统本身就大量用到了PreferenceActivity来对系统进行信息配置和管理,那么它是怎么保存数据的呢,如何创建PrefenceActivity的呢,更关键是怎样触发相应事件的呢。

Android系统有四种基本的数据保存方法,一是SharedPreference,二是文件,三是SQLite,四是 ContentProvider。PreferenceActivity是如何保存的数据,其实就是通过SharedPreference键值对的形式来保存数据的。


我们以一个例子来说明如何在Android系统中制作一个设置的功能。先看下该例子的大概框架图:


MainActivity.javas是我们的主画面,MyPreferenceActivity.java是设置页面;在res/xml目录下有个mypreference.xml的文件,该文件是设置页面的布局文件,在添加该xml文件的时候,注意是选择的不是 Layout,而是Preference,而且注意Folder路径是 res/xml。


mypreference.xml文件中的代码如下:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >

    <PreferenceCategory
        android:key="set_local"
        android:title="我的位置" >
        <CheckBoxPreference
            android:defaultValue="true"
            android:key="apply_wifi"
            android:summary="使用无线网络在应用程序(例如Google地图)中查看位置"
            android:title="使用无线网络" />
        <CheckBoxPreference
            android:key="apply_gps"
            android:summary="定位到街道级别(需要消耗更多的电量以及天气允许)"
            android:title="使用GPS" >
        </CheckBoxPreference>
        <ListPreference
            android:key="depart_value"
            android:title="部门设置"
            android:dialogTitle="部门"
            android:entries="@array/department"
            android:entryValues="@array/department_value"
	    android:defaultValue="1"/>
    </PreferenceCategory>

</PreferenceScreen>

 

MyPreferenceActivity.java 的代码如下,该类需要继承PreferenceActivity。()

package com.example.androidtest_preference;

import android.os.Bundle;
import android.preference.PreferenceActivity;

public class MyPreferenceActivity extends PreferenceActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		addPreferencesFromResource(R.xml.mypreference); 
		
	}

}

MainActivity.java的代码如下:

package com.example.androidtest_preference;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends Activity {

	private static final int SET  = Menu.FIRST;
	private static final int EXIT  = Menu.FIRST + 1;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
//		getMenuInflater().inflate(R.menu.main, menu);
		Log.d("MainActivity", "onCreateOptionsMenu");
		menu.add(0, SET, 0, "设置");
		menu.add(0, EXIT, 0, "退出");
		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		Log.d("MainActivity", "onOptionsItemSelected");
		switch (item.getItemId()) {
		case SET:
			Intent intent  = new Intent(this,MyPreferenceActivity.class);
			startActivity(intent);
			break;
		case EXIT:
			this.finish();
			break;
		default:
			break;
		}
		return super.onOptionsItemSelected(item);
	}

	@Override
	public void onOptionsMenuClosed(Menu menu) {
		super.onOptionsMenuClosed(menu);
		Log.d("MainActivity", "onOptionsMenuClosed");
	}
	
	
	
}

array.xml 中的内容如下(该文件中的数组被mypreference.xml引用):

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string-array name="department">
        <item>综合部</item>
        <item>外贸部</item>
        <item>行政部</item>
    </string-array>
    <string-array name="department_value">
        <item>001</item>
        <item>002</item>
        <item>003</item>
    </string-array>

</resources>


同时不要忘记在AndroidManifest.xml文件中加入MyPreferenceActivity.java的配置。

设置画面的运行结果如下:




以上即是使用PrefereneActivity做成设置画面的步骤。



通过PreferenceActivity,我们已经把画面做成了,但是具体该怎么操作数据呢。


Preference类提供了以下两个接口,用于监听Preference的动作。

    public interface OnPreferenceChangeListener {
        /**
         * Called when a Preference has been changed by the user. This is
         * called before the state of the Preference is about to be updated and
         * before the state is persisted.
         *
         * @param preference The changed Preference.
         * @param newValue The new value of the Preference.
         * @return True to update the state of the Preference with the new value.
         */
        boolean onPreferenceChange(Preference preference, Object newValue)

       当Preference的值被用户改变的时候,该方法被调用。

       例如,我们在mypreference.xml 文件中定义的ListPreference的默认值是1.

       当用操作ListPreference,选择第二项的时候,该方法就会被调用。

       方法的第一个参数就是我们操作的ListPreference的引用,

       方法的第二个参数是该Preference的最新值2,(因为我们选择了第二项),

       第二项对象的value值为2.

    }


    /**
     * Interface definition for a callback to be invoked when a {@link Preference} is
     * clicked.
     */
    public interface OnPreferenceClickListener {
        /**
         * Called when a Preference has been clicked.
         *
         * @param preference The Preference that was clicked.
         * @return True if the click was handled.
         */
        boolean onPreferenceClick(Preference preference);

        当画面中Preference被点击的时候,调用该方法。

        在方法内容我们可以加入自己的逻辑处理。
    }


1)通过getPreferenceManager().setSharedPreferencesName(SETTING);

将画面中的preference和那么为SETTTING的Sharepreference关联到一起。

2) 通过【android:key】获取到画面中的preference。

    list = (ListPreference) this.findPreference("depart_value");

    "depart_value"是在mypreference.xml文件中定义的key值。

3)给Preferenc 设置监听器。

 list.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {

@Override
   public boolean onPreferenceChange(Preference preference, Object newValue) {

      // 当pfeference的值发生变化的时候,在这里进行处理,将变化后的值

         保存在步骤1)中关联到的SharePreferece中。 (具体请参考完整的代码)

         如果其他画面加了OnSharedPreferenceChangeListener监听,则能够实时的

         接收到通知。

         同时在当前画面可以更新preferece的显示信息。 (具体请参考完整的代码)

}

list.setOnPreferenceClickListener(new OnPreferenceClickListener() {

   @Override
   public boolean onPreferenceClick(Preference preference) {
    return true;
   }

}

修改后的MyPreferenceActivity代码:

package com.example.androidtest_preference;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceActivity;

public class MyPreferenceActivity extends PreferenceActivity {

	private ListPreference list = null;

	private static final String SETTING = "SETTING";

	private static final int DEPATMENT_VALUE = 1;
	private static final String DEPATMENT_KEY = "depart_value";

	@SuppressWarnings("deprecation")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// 将画面中的preference和那么为SETTTING的Sharepreference关联到一起。
		getPreferenceManager().setSharedPreferencesName(SETTING);
		addPreferencesFromResource(R.xml.mypreference);
		initView();
		setViewInfo();
	}

	private void initView() {
		list = (ListPreference) this.findPreference("depart_value");
		list.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {

			// 当Preference的值被用户改变的时候,该方法被调用。
			// 例如,我们在mypreference.xml 文件中定义的ListPreference的默认值是1.
			// 当用操作ListPreference,选择第二项的时候,该方法就会被调用。
			// 方法的第一个参数就是我们操作的ListPreference的引用,
			// 方法的第二个参数是该Preference的最新值2,(因为我们选择了第二项),
			// 第二项对象的value值为2.
			@Override
			public boolean onPreferenceChange(Preference preference,
					Object newValue) {

				// 保存在步骤1)中关联到的SharePreferece中。
				SharedPreferences sharedPreferences = getSharedPreferences(
						SETTING, Context.MODE_PRIVATE);
				Editor editor = sharedPreferences.edit();
				// 这里需要注意一下,
				// preference.getKey()取得的是mypreference.xml中ListPreference的区别Flg。
				// putString 方法的第一个参数是SharedPreferences中某个value的key值。
				// 这两个key值的名称必须一致。否则会出现问题。
				editor.putString(preference.getKey(), String.valueOf(newValue)).commit();
				// 更新当前画面中preference的显示信息。
				setViewInfo();
				return true;
			}
		});
		// 当画面中Preference被点击的时候,调用该方法。
		// 在方法内容我们可以加入自己的逻辑处理。
		list.setOnPreferenceClickListener(new OnPreferenceClickListener() {

			@Override
			public boolean onPreferenceClick(Preference preference) {
				return true;
			}
		});
	}

	/**
	 * 从SharedPreferences中取得变化后的信息,更新当前画面中list的Summary显示内容
	 */
	private void setViewInfo() {
		SharedPreferences sharedPreferences = getSharedPreferences(SETTING,Context.MODE_PRIVATE);
		String tempDepartValue = sharedPreferences.getString(DEPATMENT_KEY,String.valueOf(DEPATMENT_VALUE));
		list.setSummary(tempDepartValue);
	}
}



运行效果:

1)默认状态


2)选择第二项后  Summary变为2.

在当前画面中ListPreference的值发生变化后,我们获取到并且设置到SharePreference中。

如果在其他的画面有使用到SharePreference,怎么监听值变化呢?

在其他画面中加入OnSharedPreferenceChangeListener就可以了。
















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值