EditTextPreference 設置 defaultValue 的數據類型
我們經常使用PreferenceFragment來設置應用的一些配置參數,通常我們需要自定義一個xml文件,用來顯示有那些參數,並定義這些參數的默認值。例如下面:
<EditTextPreference
android:defaultValue="0000"
android:dialogTitle="Test"
android:key="test"
android:summary="0000"
android:title="Test"/>
我們想設置一個key爲“test”默認值爲字符串“0000”的Preference
,在PreferenceFragment
中通過addPreferencesFromResource()
方法將這個xml文件中的Preference
添加進來,可是在打開這個EditTextPreference
之後發現默認值被設置爲“0”,不是我們設想的“0000”。爲什麼會這樣,我們來看下源碼:
public void addPreferencesFromResource(int preferencesResId) {
requirePreferenceManager();
setPreferenceScreen(mPreferenceManager.inflateFromResource(getActivity(),
preferencesResId, getPreferenceScreen()));
}
中間代碼忽略…最後跟蹤到下面這個方法:
@Override
protected Object onGetDefaultValue(TypedArray a, int index) {
return a.getString(index);
}
然後看一下a.getString(index)
的方法體:
public String getString(int index) {
if (mRecycled) {
throw new RuntimeException("Cannot make calls to a recycled instance!");
}
index *= AssetManager.STYLE_NUM_ENTRIES;
final int[] data = mData;
final int type = data[index+AssetManager.STYLE_TYPE];
if (type == TypedValue.TYPE_NULL) {
return null;
} else if (type == TypedValue.TYPE_STRING) {
return loadStringValueAt(index).toString();
}
TypedValue v = mValue;
if (getValueAt(index, v)) {
Log.w(Resources.TAG, "Converting to string: " + v);
CharSequence cs = v.coerceToString();
return cs != null ? cs.toString() : null;
}
Log.w(Resources.TAG, "getString of bad type: 0x" + Integer.toHexString(type));
return null;
}
查看源碼發現需要一個TypedValue.TYPE_STRING
的數據類型才能正確解析“0000”字符串,那麼怎麼才能把“0000”定義成TypedValue.TYPE_STRING
的數據類型呢,答案其實很簡單,我們在字符串資源文件strings.xml文件裏定義一個字符串資源:
<resources>
<string name="test">0000</string>
</resources>
然後將android:defaultValue
的值改爲字符串引用:
<EditTextPreference
android:defaultValue="@string/test"
android:dialogTitle="Test"
android:key="test"
android:summary="0000"
android:title="Test"/>
這樣TypedArray 自然會識別字符串類型,再也不會轉換錯誤了,其它類型都可以這樣修改,這樣修改的好處是保證默認值數據是你希望的那樣。
注意Preference中的android:defaultValue默認只支持這幾種數據類型: boolean, float, integer, reference, string。