Android - Как настроить пользовательский макет для PreferenceActivity в Android 3.0?
Я разрабатываю приложение с minSdkVersion = "11", то есть приложение для планшетов и Android 4.0 и новее. Я изучил интернет по этой теме, но не нашел много.
Чтобы реализовать пользовательский макет для предыдущих версий Android SDK, нам просто нужно создать макет (например, preference.xml) с помощью ListView, а его id равен android.R.id.list и использовать метод setContentView.
preference.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"
android:orientation="vertical" >
<ListView android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</RelativeLayout>
В Android 3.0 все изменилось, и настройки реализованы с использованием фрагментов. Так выглядит файл preference_headers.xml:
<preference-headers
xmlns:android="http://schemas.android.com/apk/res/android">
<header android:fragment="com.example.MyPreferenceActivity$GeneralSettingsFragment"
android:title="General"
android:summary="Common settings." />
<header
android:title="Example.com" >
<intent android:action="android.intent.action.VIEW"
android:data="http://www.example.com" />
</header>
</preference-headers>
MyPreferenceActivity.java:
public class MyPreferenceActivity extends PreferenceActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.preference);
// Add a button to the header list.
if (hasHeaders()) {
Button button = new Button(this);
button.setText("Log out");
setListFooter(button);
}
}
/**
* Populate the activity with the top-level headers.
*/
@Override
public void onBuildHeaders(List<Header> target) {
loadHeadersFromResource(R.xml.preference_headers, target);
}
public static class GeneralSettingsFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.fragmented_preferences);
}
}
}
Теперь, если я запустил MyPreferenceActivity, я увижу эту ошибку в LogCat:
> java.lang.IllegalArgumentException: No view found for id 0x10202be for
> fragment GeneralSettingsFragment{4077f8c0 #0 id=0x10202be}
> E/AndroidRuntime(17103): at
> android.app.FragmentManagerImpl.moveToState(FragmentManager.java:729)
> E/AndroidRuntime(17103): at
> android.app.FragmentManagerImpl.moveToState(FragmentManager.java:926)
> E/AndroidRuntime(17103): at
> android.app.FragmentManagerImpl.moveToState(FragmentManager.java:909)
> E/AndroidRuntime(17103): at
> android.app.FragmentManagerImpl.dispatchStart(FragmentManager.java:1584)
> E/AndroidRuntime(17103): at
> android.app.Activity.performStart(Activity.java:4377)
> E/AndroidRuntime(17103): at
> android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1724)
> E/AndroidRuntime(17103): ... 11 more
Я знаю, что вызывает эту проблему. FragmentManager просто не может найти представление для вставки фрагмента GeneralSettingsFragment in. Но я не знаю, как его решить.
Кстати, если я запускаю одно и то же приложение на Android 4.0, я могу увидеть первую операцию с заголовками. Но если я нажму на General, приложение выйдет из строя, и я получу аналогичную ошибку в LogCat:
java.lang.IllegalArgumentException: No view found for id 0x10202cd for fragment GeneralSettingsFragment{4134b4e0 #0 id=0x10202cd}
E/AndroidRuntime(2170): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:789)
E/AndroidRuntime(2170): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:998)
E/AndroidRuntime(2170): at android.app.BackStackRecord.run(BackStackRecord.java:622)
E/AndroidRuntime(2170): at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1330)
E/AndroidRuntime(2170): at android.app.Activity.performStart(Activity.java:4474)
E/AndroidRuntime(2170): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1928)
Ответы
Ответ 1
У меня была такая же проблема, как и вы.
Я пробовал много всего, но вот мой полный код:
https://github.com/iRail/BeTrains-for-Android/blob/master/src/tof/cv/mpp/MyPreferenceActivity.java
Трюк заключается в том, чтобы добавить setContentView в раздел onBuildHeaders, но НЕ в onCreate.
Я также сделал некоторые тесты в фрагменте и не совсем уверен, почему это работает, но я обещаю вам: у меня есть настраиваемый макет в разделе заголовка планшета!
https://github.com/iRail/BeTrains-for-Android/blob/master/src/tof/cv/mpp/view/StockPreferenceFragment.java
Ответ 2
Я пробовал этот код для своего приложения
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="@string/PreferencesActivity.GeneralSettingsCategoryTitle">
<Preference
android:title="yor title"
android:summary="your summary"
android:key="key to access preference" />
<Preference
android:title="@string/"
android:summary="@string/"
android:key="key2" />
<PreferenceScreen
android:key="key3"
android:title="@string/"
android:summary="@string/">
<CheckBoxPreference
android:title="@string/"
android:defaultValue="false"
android:summary="@string/"
android:key="key4" />
<CheckBoxPreference
android:title="@string/"
android:defaultValue="true"
android:summary="@string/"
android:key="key5" />
<ListPreference
android:title="@string/"
android:summary="@string/"
android:key="key6"
android:defaultValue="buttons"
android:entries="@array/"
android:entryValues="@array/" />
....
</prefefenceScreen>
</preferenceCategory>
</preferenceScreen>
enter code here
Ответ 3
вам не нужно устанавливатьContenView. в этом примере случае массовая разбивка выполняется через заголовки и связанные фрагменты, другие слова автоматически.