为地震Viewer创建一个Preference页

   

    在第5章,你已经创建了一个地震监视器,它能基于Internet种子显示出最近的地震列表。

     

    在接下来的例子里,你将为这个地震Viewer创建一个Preference页,来允许用户配置应用程序设定来获得更加个性的体验。你将为程序提供以下功能:自动更新、更新频率和最小地震级别的过滤。

     

    在本章的后面,你将进一步扩展这个例子,通过创建一个Content Provider来保存地震数据和与其它应用程序共享数据。

     

    1. 打开你在第5章创建的Earthquake工程。

     

    添加“Preference”屏幕中显示标签的字符串资源。另外,为新的菜单项添加一个字符串,来允许用户访问Preference屏幕。

     

    <?xml version=”1.0” encoding=”utf-8”?>

    <resources>

    <string name=”app_name”>Earthquake</string>

    <string name=”quake_feed”>

    http://earthquake.usgs.gov/eqcenter/catalogs/1day-M2.5.xml

    </string>

    <string name=”menu_update”>Refresh Earthquakes</string>

    <string name=”auto_update_prompt”>Auto Update?</string>

    <string name=”update_freq_prompt”>Update Frequency</string>

    <string name=”min_quake_mag_prompt”>Minimum Quake Magnitude</string>

    <string name=”menu_preferences”>Preferences</string>

    </resources>

     

    2. 创建一个新的preferences.xml layout资源,来未Preferences Activity布局UI。包括一个Checkbox来显示“自动更新”的切换,Spinner来选择更新的频率和级别过滤。

     

    <LinearLayout

    xmlns:android=”http://schemas.android.com/apk/res/android”

    android:orientation=”vertical”

    android:layout_width=”fill_parent”

    android:layout_height=”fill_parent”>

    <TextView

    android:layout_width=”fill_parent”

    android:layout_height=”wrap_content”

    android:text=”@string/auto_update_prompt”

    />

    <CheckBox android:id=”@+id/checkbox_auto_update”

    android:layout_width=”fill_parent”

    android:layout_height=”wrap_content”

    />

    <TextView

    android:layout_width=”fill_parent”

    android:layout_height=”wrap_content”

    android:text=”@string/update_freq_prompt”

    />

    <Spinner

    android:id=”@+id/spinner_update_freq”

    android:layout_width=”fill_parent”

    android:layout_height=”wrap_content”

    android:drawSelectorOnTop=”true”

    />

    <TextView

    android:layout_width=”fill_parent”

    android:layout_height=”wrap_content”

    android:text=”@string/min_quake_mag_prompt”

    />

    <Spinner

    android:id=”@+id/spinner_quake_mag”

    android:layout_width=”fill_parent”

    android:layout_height=”wrap_content”

    android:drawSelectorOnTop=”true”

    />

    <LinearLayout

    android:orientation=”horizontal”

    android:layout_width=”fill_parent”

    android:layout_height=”wrap_content”>

    <Button

    android:id=”@+id/okButton”

    android:layout_width=”wrap_content”

    android:layout_height=”wrap_content”

    android:text=”@android:string/ok”

    />

    <Button

    android:id=”@+id/cancelButton”

    android:layout_width=”wrap_content”

    android:layout_height=”wrap_content”

    android:text=”@android:string/cancel”

    />

    </LinearLayout>

    </LinearLayout>

     

    3. /res/values/arrays.xml文件中创建四个数组资源。它们负责提供更新频率和最小级别的值。

     

    <?xml version=”1.0” encoding=”utf-8”?>

    <resources>

    <string-array name=”update_freq_options”>

    <item>Every Minute</item>

    <item>5 minutes</item>

    <item>10 minutes</item>

    <item>15 minutes</item>

    <item>Every Hour</item>

    </string-array>

    <array name=”magnitude”>

    <item>3</item>

    <item>5</item>

    <item>6</item>

    <item>7</item>

    <item>8</item>

    </array>

    <string-array name=”magnitude_options”>

    <item>3</item>

    <item>5</item>

    <item>6</item>

    <item>7</item>

    <item>8</item>

    </string-array>

    <array name=”update_freq_values”>

    <item>1</item>

    <item>5</item>

    <item>10</item>

    <item>15</item>

    <item>60</item>

    </array>

    </resources>

     

    4. 创建Preferences Activity。它将用于显示应用程序的Preference。重写onCreate方法来显示第2步中创建的layout,并且获得Checkbox和两个Spinner控件的引用。然后调用一下populateSpinners方法。

     

    package com.paad.earthquake;

    import android.app.Activity;

    import android.content.SharedPreferences;

    import android.content.SharedPreferences.Editor;

    import android.os.Bundle;

    import android.view.View;

    import android.widget.ArrayAdapter;

    import android.widget.Button;

    import android.widget.CheckBox;

    import android.widget.Spinner;

     

    public class Preferences extends Activity {

    CheckBox autoUpdate;

    Spinner updateFreqSpinner;

    Spinner magnitudeSpinner;

     

    @Override

    public void onCreate(Bundle icicle) {

    super.onCreate(icicle);

    setContentView(R.layout.preferences);

    updateFreqSpinner = (Spinner)findViewById(R.id.spinner_update_freq);

    magnitudeSpinner = (Spinner)findViewById(R.id.spinner_quake_mag);

    autoUpdate = (CheckBox)findViewById(R.id.checkbox_auto_update);

    populateSpinners();

    }

     

    private void populateSpinners() {

    }

    }

     

    5. 填充populateSpinners方法,使用ArrayAdapter绑定每个Spinner到相应的数组上。

     

    private void populateSpinners()

    {

    // Populate the update frequency spinner

    ArrayAdapter<CharSequence> fAdapter;

    fAdapter = ArrayAdapter.createFromResource(this, R.array.update_freq_options,

    android.R.layout.simple_spinner_item);

    fAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

    updateFreqSpinner.setAdapter(fAdapter);

     

    // Populate the minimum magnitude spinner

    ArrayAdapter<CharSequence> mAdapter;

    mAdapter = ArrayAdapter.createFromResource(this, R.array.magnitude_options,

    android.R.layout.simple_spinner_item);

    mAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

    magnitudeSpinner.setAdapter(mAdapter);

    }

     

    6. Shared Preference的标识添加公共的静态字符串值,以及为每个Preference值添加键值。更新onCreate方法,来获取保存的Shared Preference,并调用updateUIFromPreferences方法。在updateUIFromPreferences方法,通过get<type>方法获得在Shared Preference中保存的值并更新到当前UI上。

     

    public static final String USER_PREFERENCE = “USER_PREFERENCES”;

    public static final String PREF_AUTO_UPDATE = “PREF_AUTO_UPDATE”;

    public static final String PREF_MIN_MAG = “PREF_MIN_MAG”;

    public static final String PREF_UPDATE_FREQ = “PREF_UPDATE_FREQ”;

    SharedPreferences prefs;

     

    @Override

    public void onCreate(Bundle icicle) {

    super.onCreate(icicle);

    setContentView(R.layout.preferences);

    updateFreqSpinner = (Spinner)findViewById(R.id.spinner_update_freq);

    magnitudeSpinner = (Spinner)findViewById(R.id.spinner_quake_mag);

    autoUpdate = (CheckBox)findViewById(R.id.checkbox_auto_update);

    populateSpinners();

    prefs = getSharedPreferences(USER_PREFERENCE, Activity.MODE_PRIVATE);

    updateUIFromPreferences();

    }

     

    private void updateUIFromPreferences() {

    boolean autoUpChecked = prefs.getBoolean(PREF_AUTO_UPDATE, false);

    int updateFreqIndex = prefs.getInt(PREF_UPDATE_FREQ, 2);

    int minMagIndex = prefs.getInt(PREF_MIN_MAG, 0);

    updateFreqSpinner.setSelection(updateFreqIndex);

    magnitudeSpinner.setSelection(minMagIndex);

    autoUpdate.setChecked(autoUpChecked);

    }

     

    7. onCreate方法中,为OKCancel按钮添加事件处理函数。Cancel关闭Activity,而OK应该先调用savePreferences方法。

     

    @Override

    public void onCreate(Bundle icicle) {

    super.onCreate(icicle);

    setContentView(R.layout.preferences);

    updateFreqSpinner = (Spinner)findViewById(R.id.spinner_update_freq);

    magnitudeSpinner = (Spinner)findViewById(R.id.spinner_quake_mag);

    autoUpdate = (CheckBox)findViewById(R.id.checkbox_auto_update);

    populateSpinners();

    prefs = getSharedPreferences(USER_PREFERENCE, Activity.MODE_PRIVATE);

    updateUIFromPreferences();

     

    Button okButton = (Button) findViewById(R.id.okButton);

    okButton.setOnClickListener(new View.OnClickListener() {

    public void onClick(View view)

    {

    savePreferences();

    Preferences.this.setResult(RESULT_OK);

    finish();

    }

    });

     

    Button cancelButton = (Button) findViewById(R.id.cancelButton);

    cancelButton.setOnClickListener(new View.OnClickListener() {

    public void onClick(View view)

    {

    Preferences.this.setResult(RESULT_CANCELED);

    finish();

    }

    });

    }

     

    private void savePreferences() {

    }

     

    8. 填充savePreference方法来记录当前的设置项,把UI的选择结果存到Shared Preference对象中。

     

    private void savePreferences() {

    int updateIndex = updateFreqSpinner.getSelectedItemPosition();

    int minMagIndex = magnitudeSpinner.getSelectedItemPosition();

    boolean autoUpdateChecked = autoUpdate.isChecked();

    Editor editor = prefs.edit();

    editor.putBoolean(PREF_AUTO_UPDATE, autoUpdateChecked);

    editor.putInt(PREF_UPDATE_FREQ, updateIndex);

    editor.putInt(PREF_MIN_MAG, minMagIndex);

    editor.commit();

    }

     

    9. 以上完成了Preferences Activity。为了能在应用程序中能访问它,应将其添加到应用程序的manifest中。

     

    <activity android:name=”.Preferences”

    android:label=”Earthquake Preferences”>

    </activity>

     

    10. 现在,回到Earthquake Activity中,为显示Preferences Activity添加菜单项。扩展onCreateOptionsMenu方法,在其中添加一个新的项目来打开Preferences Activity

     

    static final private int MENU_PREFERENCES = Menu.FIRST+1;

    @Override

    public boolean onCreateOptionsMenu(Menu menu) {

    super.onCreateOptionsMenu(menu);

    menu.add(0, MENU_UPDATE, Menu.NONE, R.string.menu_update);

    menu.add(0, MENU_PREFERENCES, Menu.NONE, R.string.menu_preferences);

    return true;

    }

     

    11. 修改onOptionsItemSelected方法,当选择新的菜单项时显示Preferences Activity。创建一个显式的Intent,并将其传入startActivityForResult中。它将启动Preferences画面,并在其保存后通过onActivityResult处理函数通知Earthquake类。

     

    private static final int SHOW_PREFERENCES = 1;

    public boolean onOptionsItemSelected(MenuItem item) {

    super.onOptionsItemSelected(item);

    switch (item.getItemId())

    {

    case (MENU_UPDATE):

    {

    refreshEarthquakes();

    return true;

    }

    case (MENU_PREFERENCES):

    {

    Intent i = new Intent(this, Preferences.class);

    startActivityForResult(i, SHOW_PREFERENCES);

    return true;

    }

    }

    return false;

    }

     

    12. 启动应用程序,从Activity 菜单中选择PreferencesPreferences Activity应该显示如图6-1.

     

    6-1

     

    13. 所有剩下来的就是应用设置到Earthquake上。自动更新的实现将留到第8章,在那里,你将学习如何使用Service和后台线程。现在,你可以在适当的位置添加框架代码,并应用地震级别过滤。

     

    14. 创建updateFromPreferences方法并读取Shared Preference中的值,将这些值存到实例的变量中。

     

    int minimumMagnitude = 0;

    boolean autoUpdate = false;

    int updateFreq = 0;

    private void updateFromPreferences()

    {

    SharedPreferences prefs = getSharedPreferences(Preferences.USER_PREFERENCE, Activity.MODE_PRIVATE);

    int minMagIndex = prefs.getInt(Preferences.PREF_MIN_MAG, 0);

    if (minMagIndex < 0)

    minMagIndex = 0;

    int freqIndex = prefs.getInt(Preferences.PREF_UPDATE_FREQ, 0);

    if (freqIndex < 0)

    freqIndex = 0;

    autoUpdate = prefs.getBoolean(Preferences.PREF_AUTO_UPDATE, false);

    Resources r = getResources();

     

    // Get the option values from the arrays.

    int[] minMagValues = r.getIntArray(R.array.magnitude);

    int[] freqValues = r.getIntArray(R.array.update_freq_values);

     

    // Convert the values to ints.

    minimumMagnitude = minMagValues[minMagIndex];

    updateFreq = freqValues[freqIndex];

    }

     

    15. 通过更新addNewQuake方法来应用级别过滤。在将Quake对象添加到list之前检查一下Quake的级别。

     

    private void addNewQuake(Quake _quake) {

    if (_quake.getMagnitude() > minimumMagnitude)

    {

    // Add the new quake to our list of earthquakes.

    earthquakes.add(_quake);

    // Notify the array adapter of a change.

    aa.notifyDataSetChanged();

    }

    }

     

    16. 重写onActivityResult方法,当保存了Preferences Activity的变更后调用updateFromPreferences方法和refresh方法。

     

    @Override

    public void onActivityResult(int requestCode, int resultCode,Intent data)

    {

    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == SHOW_PREFERENCES)

    if (resultCode == Activity.RESULT_OK) {

    updateFromPreferences();

    refreshEarthquakes();

    }

    }

     

    17. 最后,在onCreate方法中调用updateFromPreferences(在调用refreshEarthquake方法之前),确保设置项在Activity第一次启动时应用了。

     

    @Override

    public void onCreate(Bundle icicle) {

    super.onCreate(icicle);

    setContentView(R.layout.main);

    earthquakeListView = (ListView)this.findViewById(R.id.earthquakeListView);

    earthquakeListView.setOnItemClickListener(new OnItemClickListener() {

    public void onItemClick(AdapterView _av, View _v, int _index, long arg3)

    {

    selectedQuake = earthquakes.get(_index);

    showDialog(QUAKE_DIALOG);

    }

    });

    int layoutID = android.R.layout.simple_list_item_1;

    aa = new ArrayAdapter<Quake>(this, layoutID, earthquakes);

    earthquakeListView.setAdapter(aa);

    updateFromPreferences();

    refreshEarthquakes();

    }

posted on 2009-08-06 15:15  xirihanlin  阅读(930)  评论(1编辑  收藏  举报