在部落格《android基礎知識07:SharedPreferences和PreferenceActivity》中我們介紹了SharedPreferences和PreferenceActivity的基本原理。本文我們將自頂一個activity來實現PreferenceActivity的功能。 通常我們看到設定介面都是一個屏的,一般這都是根據PreferenceActivity來實現了。但是如果出現一種情況,我的設定項很多,在一個列表中顯示不完怎麼辦?理論上我們可以用分頁來解決,但是這個到目前我還沒有看到解決方案。另外一種,就是這裡需要介紹的分頻的方式。
在這裡,你點擊下方四個按鈕,則會進入對應的設定項。
對於這種介面,有兩種可行的實現方法: 方法1:使用多個Preference.xml檔案,點擊不同的按鈕,則inflate不同的檔案。這裡存在一個問題,你必須製作4個最底下都是4個相同按鈕的布局檔案,然後根據點擊不同的按鈕進行切換布局。 方法2:使用一個布局,在使用時,隱藏或者顯示不同的部分。比如下布局檔案所示:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent" android:layout_height="fill_parent"android:orientation="vertical"><LinearLayout android:id="@+id/pref_container_ll" android:orientation="vertical"android:layout_width="fill_parent" android:layout_height="fill_parent"android:layout_weight="1" android:background="#00000000"><LayoutScrollViewandroid:id="@+id/pref_default" android:layout_xml="@layout/android_settings_function"android:visibility="visible" style="@style/Layout_FF" /><LayoutScrollViewandroid:id="@+id/pref_function" android:layout_xml="@layout/android_settings_function1"android:visibility="gone" style="@style/Layout_FF" /><LayoutScrollViewandroid:id="@+id/pref_design" android:layout_xml="@layout/android_settings_function2"android:visibility="gone" style="@style/Layout_FF"android:background="#00000000" /><LayoutScrollViewandroid:id="@+id/pref_team" android:layout_xml="@layout/android_settings_function3"android:visibility="gone" style="@style/Layout_FF" /></LinearLayout><LinearLayout android:orientation="horizontal"android:background="#7c7c7b" android:layout_width="fill_parent"android:layout_height="wrap_content" android:paddingTop="5dip" android:paddingBottom="3dip"android:paddingLeft="5dip" android:paddingRight="5dip"><Button android:id="@+id/pref_setting_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="setting" /><Button android:id="@+id/pref_function_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="function" /><Button android:id="@+id/pref_design_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="design" /><Button android:id="@+id/pref_team_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="team" /></LinearLayout></LinearLayout>
使用此布局時,點擊不同的按鈕則顯示不同的LayoutScrollView,以此來完成我們分屏的目的。
這時,據會產生一個問題,我們在使用PreferenceActivity布局檔案的那些元素時,並沒有可以做到這一點的,怎麼辦呢?簡單,自己寫。自己寫一個PreferenceView類,同時通過該類去實現屬於你自己的CheckBoxPreferenceView等等元素。 之類我們介紹一下PreferenceView的實現,其布局檔案preference.xml為:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="wrap_content" android:layout_height="wrap_content"android:layout_weight="1" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:singleLine="true" android:textAppearance="?android:attr/textAppearanceLarge" android:ellipsize="marquee" android:fadingEdge="horizontal" android:text="TITLE" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceSmall" android:maxLines="2" android:text="description" /></LinearLayout>
其代碼為:
public abstract class PreferenceView extends LinearLayout implements OnClickListener, PreferenceInterface { protected String mKey; protected String mStringValue; protected boolean mBooleanValue; protected TextView mTitleView; protected TextView mSummaryView; protected Context mContext; public PreferenceView(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; LayoutParams param = generateDefaultLayoutParams(); setClickable(true); setFocusable(true); setEnabled(true); setLayoutParams(param); setOrientation(HORIZONTAL); // setPadding(0, 0, 0, 13); setOnClickListener(this); LayoutInflater.from(context).inflate(R.layout.preference, this); } public void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) { super.onFocusChanged(gainFocus, direction, previouslyFocusedRect); if (gainFocus) { onFocus(); } else { onUnFocus(); } // setPadding(0, 0, 0, 13); } protected void onFocus() { setBackgroundResource(android.R.drawable.list_selector_background); } protected void onUnFocus() { setBackgroundColor(0x00000000); } public String getTitle() { return mTitleView.getText().toString(); } public void onClick(View v) { onFocus(); } protected void save() { SharedPreferences sp = PreferenceManager .getDefaultSharedPreferences(mContext); SharedPreferences.Editor edit = sp.edit(); save(edit); edit.commit(); }}
其中的PreferenceInterface只有兩個函數:
public void load(SharedPreferences sp);
public void save(SharedPreferences.Editor edit); 這裡大家可以對照一下系統內建的Preference的元素,就知道這個類的大概意思了。 於是對於一個CheckBoxPreferenceView ,我們該如何定義呢? 其布局檔案定義如下:
<CheckBox xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="4dip" android:layout_gravity="center_vertical" android:focusable="true" android:clickable="true" /> 其代碼為:public class CheckBoxPreferenceView extends PreferenceView implements OnCheckedChangeListener { protected CheckBox mCheckBox; private boolean mInit = false; public CheckBoxPreferenceView(Context context, AttributeSet attrs) { super(context, attrs); LayoutInflater.from(context).inflate( R.layout.simeji_preference_checkbox, this); mCheckBox = (CheckBox) getChildAt(getChildCount() - 1); //mCheckBox.setChecked(mBooleanValue); mCheckBox.setOnCheckedChangeListener(this); } public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (mInit) { save(); } } @Override public void onClick(View v) { super.onClick(v); mCheckBox.setChecked(!mCheckBox.isChecked()); //save(); } @Override public void save(SharedPreferences.Editor edit) { edit.putBoolean(mKey, mCheckBox.isChecked()); } @Override public void load(SharedPreferences sp) { mInit = false; boolean flag = sp.getBoolean(mKey, mBooleanValue); mCheckBox.setChecked(flag); mInit = true; }} 於是,你就可以像使用系統內建的CheckBoxPreference 使用這個東西了。另外,你還可以據此自己定義ListPreference或者其他控制項。