安卓 - 如何在安卓3.0中为PreferenceActivity设置自定义布局?

17

我正在开发一个最小SDK版本为"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中,偏好设置的实现方式已经发生了变化,使用了片段(Fragments)。下面是我的 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片段的视图。但我不知道该如何解决它。

顺便说一下,如果我在Android 4.0上运行相同的应用程序,那么我可以看到带有标题的第一个首选项活动。 但是,如果我点击“常规”,应用程序将崩溃,并且我将在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)

你想做什么?为什么需要自定义布局? - alexanderblom
我想要更精确地控制Preference Activity。此外,我希望它尽可能兼容较新版本的Android SDK,也就是说,我需要扩展PreferenceActivity,但不是从头开始实现。 - morphium
3个回答

4

我遇到了与你一样的问题。

我尝试了很多方法,但这是我的全部代码:

https://github.com/iRail/BeTrains-for-Android/blob/master/src/tof/cv/mpp/MyPreferenceActivity.java

关键是在onBuildHeaders部分中添加setContentView,而不是在onCreate中添加。

我还在片段中进行了一些测试,但不确定为什么会起作用,但我向你保证:我在平板电脑标题部分有一个自定义布局!

https://github.com/iRail/BeTrains-for-Android/blob/master/src/tof/cv/mpp/view/StockPreferenceFragment.java


链接已经失效,但我找到了它:https://github.com/iRail/BeTrains-for-Android/blob/master/BeTrains/src/main/java/tof/cv/mpp/MyPreferenceActivity.java - Glaucus
然而,在onBuildHeaders中我没有看到调用setContentView的语句。所以我不确定应该怎么想。 - Glaucus

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

-1

你不需要设置setContentView。在这个例子中,布局的填充是通过标题和相关片段完成的,换句话说是自动完成的。


我知道我不一定需要它。但在这个例子中,我将按钮添加到列表页脚。现在我想更精确地自定义视图。也许通过在活动顶部添加徽标等方式。也就是说,我需要它。我只是不明白,有很多关于PreferenceActivity自定义的示例和教程适用于Android 3.0之前的应用程序。是否不可能使其适用于API SDK大于10? - morphium

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接