我正在嘗試創建一個自定義Preference以顯示在PreferenceFragment中,如下所述:Building a Custom Preference。我的自定義偏好設置應爲SwitchPreference,但有一個額外的TextView
用於錯誤報告。Android:具有自定義首選項生命週期不一致性的PreferenceFragment?
我已經實現了一切並且UI看起來很好,但是當我的PreferenceFragment被顯示時,我無法初始化這個首選項!
的文檔Preference.onBindView()
指出:
這是爲了搶在佈局 和他們的自定義視圖引用設置屬性的好地方。
所以我做:
@Override
protected void onBindView(View view) {
super.onBindView(view);
txtError = (TextView) view.findViewById(R.id.error);
}
public void setError(String errorMessage) {
txtError.setText(errorMessage);
notifyChanged();
}
然而,當我在PreferenceFragment.onResume()
叫CustomSwitchPreference.setError(String)
,我得到NPE因爲txtError
爲空。
我試圖找到一些解決辦法,但它看起來像有在PreferenceFragment沒有生命週期的方法,這是保證被稱爲畢竟底層Preferences
有他們Views
初始化(我檢查兩個Preference.onBindView(View)
和Preference.onCreateView(ViewGroup)
)。
此行爲沒有任何意義 - 當顯示PreferenceFragment
時,應該有一些方法來初始化底層Preferences
的UI。我怎樣才能做到這一點?
注意:致電customPreference.setTitle(String)
和customPreference.setSummary(String()
CustomPreferenceFragment.onResume()
工作正常。這僅僅是額外的TextView
我不能搶參考...
CustomSwitchPreference.java:
public class CustomSwitchPreference extends SwitchPreference {
private TextView txtError;
public CustomSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public CustomSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public CustomSwitchPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomSwitchPreference(Context context) {
super(context);
}
@Override
protected View onCreateView(ViewGroup parent) {
setLayoutResource(R.layout.custom_switch_preference_layout);
return super.onCreateView(parent);
}
@Override
protected void onBindView(View view) {
super.onBindView(view);
txtError = (TextView) view.findViewById(R.id.error);
}
public void setError(String errorMessage) {
txtError.setText(errorMessage);
notifyChanged();
}
}
CustomPreferenceFragment.java:
public class CustomPreferenceFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getPreferenceManager().setSharedPreferencesName(PREFERENCES_FILE_NAME);
addPreferencesFromResource(R.xml.application_settings);
}
@Override
public void onResume() {
super.onResume();
Preference preference = findPreference("CUSTOM_PREF");
if (preference == null ||
!CustomSwitchPreference.class.isAssignableFrom(preference.getClass()))
throw new RuntimeException("couldn't get a valid reference to custom preference");
CustomSwitchPreference customPreference = (CustomSwitchPreference) preference;
customPreference.setError("error");
}
}
custom_switch_preference_layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:layout_alignParentStart="true"
android:layout_toStartOf="@android:id/widget_frame">
<TextView
android:id="@android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:lines="1"/>
<TextView
android:id="@android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="3"/>
<TextView
android:id="@+id/error"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="3"/>
</LinearLayout>
<FrameLayout
android:id="@android:id/widget_frame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentEnd="true"/>
</RelativeLayout>
application_settings.xml:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<com.example.settings.CustomSwitchPreference
android:key="CUSTOM_PREF"/>
</PreferenceScreen>