Android 設置是每個App必不可小的東西,看似很簡單,但是初學不熟悉的很花時間去研究,特別樣式相容方面,以及有自定義設置的需求,下麵是對用法做一個總結 ...
Android 設置是每個App必不可小的東西,看似很簡單,但是初學不熟悉的很花時間去研究,特別樣式相容方面,以及有自定義設置的需求,下麵是對用法做一個總結
Preference結構
界面結構看下圖
界面主要由PrefercenScreen、PreferenceCategory和Preference三個主要部分組成
- PrefercenScreen最根的部分;
- PreferenceCategory是每個設置的分組;
Preference是具體到每個設置元素;
XML文件
XML結構層級大致如圖
<android.support.v7.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <android.support.v7.preference.PreferenceCategory android:title="preference v7"> <android.support.v7.preference.CheckBoxPreference android:defaultValue="false" android:key="key_checkbox" android:summaryOff="@string/theme_light" android:summaryOn="@string/theme_dark" android:title="Checkbox" /> </android.support.v7.preference.PreferenceCategory> </android.support.v7.preference.PreferenceScreen>
類庫
由於Android版本升級,Preference加上原生的供有四個版本類庫,根據API的最低版本使用相應的類庫,如果你的最低版本是11,使用PreferenceFragment的話就可不使用相容庫。下麵對每個包層次整理一下
android.preference
PreferenceFragment
如果你的安卓最低版本面向11以上的,可以直接使用這個包為基礎
android.support.v7.preference
android.support.v14.preference
android.support.v17.preference
這個包主要面向電視,暫時不深入研究,具體特性遲點再補充
Preference介紹
Preference
Preference 是所有設置項目的基類,很多屬性都從這個類派生出來。
它有android.preference.Preference和 android.support.v7.preference.Preference兩個部分,大致用法相同,詳細請參考文檔;從文檔可瞭解到android.preference.Preference 是針對PreferenceActivity
ListView舊款偏好而設計,而android.support.v7.preference.Preference則適合
用RecyclerView重新設計的PreferenceFragmentCompat,使用的時候對號入座就可以了;他們都是內置 SharedPreferences 以及對應的android:key屬性來存儲數據
關鍵屬性:
- android:title,顯示的標題;
- android:summary,標題下麵對應的摘要;
- android:key,存儲數據的鍵值;
- android:dependency: 這是一個鍵值,如果設置,必須依賴key這個才可以啟用;
PreferenceScreen
它是所有偏好的根節點:
- 當它放在根部的時候是不顯示的;
當它放在節點位置的顯示,點擊顯示它的子元素;
如圖:
PreferenceCategory
這個很簡單就是一個分組的效果,只要設置好標題就可以了
MultiSelectListPreference
顯示多選對話框,存儲多項數據,關鍵屬性:- android:entries,顯示欄目數據
- android:entryValues,欄目對應的值
android:defaultValue 預設值,數組
通過上面的架構發現,到v7下麵沒有了MultiSelectListPreference,只有
MultiSelectListPreferenceDialogFragmentCompat,原因不得而知,估計是google想只提供對話框給開發者自己實現,但是到了v14下麵MultiSelectListPreference回歸了,原因不深入,直接使用就可以。
<MultiSelectListPreference
android:defaultValue="@array/deflistItems"
android:dialogTitle="MultiSelectListPreferenceDialog"
android:entries="@array/listItems"
android:entryValues="@array/listItems"
android:key="key_multi_select_list_pref"
android:summary="MultiSelectListPreference summary"
android:title="MultiSelectListPreference"
/>
效果圖
ListPreference
顯示單選對話框,存儲單項數據,關鍵屬性:
- android:entries,顯示欄目數據
- android:entryValues,欄目對應的值
- android:defaultValue 預設值
ListPreference 存在原生和v7包下麵,v14只保留ListPreferenceDialogFragment
<ListPreference
android:defaultValue="Item4"
android:dialogTitle="ListPreferenceDialog"
android:entries="@array/listItems"
android:entryValues="@array/listItems"
android:key="key_list_pref"
android:summary="ListPreference summary"
android:title="ListPreference"
/>
效果圖:
EditTextPreference
EditTextPreference繼承DialogPreference,然後編輯對戶框可以輸入文字並保存
EditTextPreference存在原生和v7包下麵,v14只保留EditTextPreferenceDialogFragment
關鍵屬性:
- android:defaultValue 預設值
<EditTextPreference
android:defaultValue="defaultValue"
android:key="key_edittext"
android:summary="EditTextPreference summary"
android:title="EditTextPreference"
/>
效果圖
CheckBoxPreference
選擇框偏好,CheckBoxPreference存在原生和v7包下麵
關鍵屬性:
- android:defaultValue 預設值
- android:summaryOff: 取消選擇的時候顯示文字
- android:summaryOn:選擇的時候顯示文字
<CheckBoxPreference
android:defaultValue="false"
android:key="key_checkbox"
android:summaryOff="@string/theme_light"
android:summaryOn="@string/theme_dark"
android:title="Checkbox"
/>
效果圖
SwitchPreference
開關編好,使用也比較簡單,原生和v14都有,v7下麵是SwitchPreferenceCompat
關鍵屬性:
- android:defaultValue 預設值
- android:summaryOff: 關閉時候顯示文字
- android:summaryOn: 開啟時候顯示文字
- android:switchTextOff: 關閉時候開關上顯示的文字
android:switchTextOn:開啟時候開關上顯示的文字
<SwitchPreference android:defaultValue="false" android:switchTextOff="@string/theme_light" android:switchTextOn="@string/theme_dark" android:summaryOff="@string/theme_light" android:summaryOn="@string/theme_dark" android:title="SwitchPreference"/> <android.support.v7.preference.SwitchPreferenceCompat android:defaultValue="false" android:summaryOff="@string/theme_light" android:summaryOn="@string/theme_dark" android:switchTextOff="@string/theme_light" android:switchTextOn="@string/theme_dark" android:title="SwitchPreferenceCompat"/> <android.support.v14.preference.SwitchPreference android:defaultValue="false" android:key="key_dark_theme_v14" android:switchTextOff="@string/theme_light" android:switchTextOn="@string/theme_dark" android:summaryOff="@string/theme_light" android:summaryOn="@string/theme_dark" android:title="v14.preference.SwitchPreference"/>
經過測試,SwitchPreferenceCompat 全平臺material design風格,開關樣式如圖看出
android.support.v14.preference.SwitchPreference和SwitchPreference Android5.0以下,按鈕還是保留老樣式,可以顯示文字
效果圖
RingtonePreference
鈴聲選擇編好,只存在原生包上面
關鍵屬性:
android:ringtoneType 鈴聲類型分四個選項:
- alarm:只顯示鬧鐘聲
- all: 顯示所有
- notification: 只顯示通知聲
ringtone 只顯示鈴聲
android:showDefault: 是否顯示預設選項,預設顯示
android:showSilent 是否顯示靜音選項,預設顯示
效果:
SeekBarPreference
微調偏好設置,SeekBarPreference只在v7包下存在
關鍵屬性
app:showSeekBarValue: 是否顯示進度數字
android:defaultValue: 預設值<android.support.v7.preference.SeekBarPreference android:key="key_seekbar" android:title="SeekBarPreference" app:showSeekBarValue="false" android:defaultValue="50" />
DropDownPreference
和ListPreference差不多,只不過是用下拉的樣式代替對話框
<android.support.v7.preference.DropDownPreference android:defaultValue="Item4" android:dialogTitle="DropDownDialog" android:entries="@array/listItems" android:entryValues="@array/listItems" android:summary="DropDownPreference summary" android:title="DropDownPreference" />
效果圖:
Preference自定義
以上偏好都不能滿足的時候需要自定義,例如我的App軟體上定義了一個關於的對話框
先看看效果是這樣的:
我們需要定義preference,通過繼承自定義DialogPreferece,代碼如下
public class AboutDialogPreference extends DialogPreference {
public static final String KEY_ABOUT_DIALOG = "key_about_dialog";
public AboutDialogPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setKey(KEY_ABOUT_DIALOG);
setTitle(R.string.about);
setSummary(getContext().getString(R.string.app_name) + PkgUtils.get(getContext()).getAppVerName());
}
}
- 然後自定義對話框
關鍵一點,newInstance()必須帶上AboutDialogPreference的key,否則會出錯
```
public class AboutPreferenceDialogFragment extends PreferenceDialogFragmentCompat {
public static AboutPreferenceDialogFragment newInstance() {
Bundle args = new Bundle();
args.putString(ARG_KEY, AboutDialogPreference.KEY_ABOUT_DIALOG);
AboutPreferenceDialogFragment fragment = new AboutPreferenceDialogFragment();
fragment.setArguments(args);
return fragment;
}
@Override
protected View onCreateDialogView(Context context) {
return View.inflate(context, R.layout.fragment_preference_about_dialog, null);
}
@Override
protected void onBindDialogView(View view) {
AppCompatTextView messageView = (AppCompatTextView) view;
messageView.setText(getInfo());
}
private String getInfo() {
String systemInfo = getString(R.string.model) + " " + Build.MODEL + "\n"
- getString(R.string.system) + " Android "
- Build.VERSION.RELEASE + "(API:" + Build.VERSION.SDK_INT + ")";
PackageInfo info = PkgUtils.get(getContext()).getPackageInfo(getContext().getPackageName());
String pkg = info != null ? info.versionName + (BuildConfig.DEBUG ? " debug" : "") : "";
return getString(R.string.about_intro, getString(R.string.app_name) + pkg, systemInfo);
}
@Override
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
builder.setIcon(R.mipmap.ic_launcher);
builder.setTitle(R.string.about);
builder.setNeutralButton(R.string.privacy_policy, (dialogInterface, i) -> {
TXWebViewActivity.browse(getContext(),
getContext().getString(R.string.privacy_policy),
TXApplication.URL_PRIVACY, false);
});
builder.setPositiveButton(R.string.app_detail, (dialogInterface, i) -> { IntentUtils.get(getContext()).showAppDetails(getContext().getPackageName());
});
}
@Override
public void onDialogClosed(boolean positiveResult) {
}
}
- 最後在SettingFragment主界面做處理
在onDisplayPreferenceDialog裡面判斷並且實例化AboutPreferenceDialogFragment,然後顯示對話框
public class SettingFragment extends PreferenceFragmentCompat{
@Override
public void onDisplayPreferenceDialog(Preference preference) {
DialogFragment dialogFragment = null;
if (preference instanceof AboutDialogPreference) {
dialogFragment = AboutPreferenceDialogFragment.newInstance();
}
if (dialogFragment != null) {
dialogFragment.setTargetFragment(this, 0);
dialogFragment.show(this.getFragmentManager(), "");
} else {
super.onDisplayPreferenceDialog(preference);
}
}
}
```
總結
- Preference掌握關鍵必須理清類的集成關係,主要是Preference,分對話框Preference和普通雙態Preference,並且掌握他們的擴展的
- PreferenceActivity和PreferenceFragment模式的差異
- 理清每個支持庫的差異,多在模擬器實踐驗證
- 掌握關鍵屬性,多看文檔
更詳細請看:
http://tinyx.cc/blog/android/android-preference.html