7

我有 PreferenceFragment 和一个 PreferenceActivity ,我以这种方式从 XML 文件中添加标头:

偏好活动

@Override
public void onBuildHeaders(List<Header> target) {  
    if(DEBUG) Log.i("PreferenceActivity", "onBuildHeaders() -> LogicAnalizerPrefs");
    if(android.os.Build.VERSION.SDK_INT >= 12) {
        loadHeadersFromResource(R.xml.preference_header_logicanalizer, target);
    }
}

偏好片段:

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if(DEBUG) Log.i("PreferenceFragment", "onCreate() -> LogicAnalizerPrefsFragment");
        int res = getActivity().getResources().getIdentifier(getArguments().getString("logicprefsheaders"), "xml", getActivity().getPackageName());
        addPreferencesFromResource(res);
    }

我拥有标题的 XML 文件是:

R.xml.preference_header_logicanalizer:

<header
        android:fragment="com.protocolanalyzer.andres.LogicAnalizerPrefsFragment"
        android:icon="@drawable/settings"
        android:title="General" >
        <extra
            android:name="logicprefsheaders"
            android:value="logicgeneral" />
    </header>
    <header
        android:fragment="com.protocolanalyzer.andres.LogicAnalizerPrefsFragment"
        android:icon="@drawable/settings"
        android:title="Canal 1" >
        <extra
            android:name="logicprefsheaders"
            android:value="c1analizerprefs" />
    </header>
    <header
        android:fragment="com.protocolanalyzer.andres.LogicAnalizerPrefsFragment"
        android:icon="@drawable/settings"
        android:title="Canal 2" >
        <extra
            android:name="logicprefsheaders"
            android:value="c2analizerprefs" />
    </header>
    <header
        android:fragment="com.protocolanalyzer.andres.LogicAnalizerPrefsFragment"
        android:icon="@drawable/settings"
        android:title="Canal 3" >
        <extra
            android:name="logicprefsheaders"
            android:value="c3analizerprefs" />
    </header>
    <header
        android:fragment="com.protocolanalyzer.andres.LogicAnalizerPrefsFragment"
        android:icon="@drawable/settings"
        android:title="Canal 4" >
        <extra
            android:name="logicprefsheaders"
            android:value="c4analizerprefs" />
    </header>

这是我的 xml 文件之一,用于在单击 Header 时显示首选项之一:

c1analizerprefs.xml:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >

    <PreferenceCategory android:title="@string/AnalyzerProtocolTitle1" >
        <ListPreference
            android:defaultValue="0"
            android:entries="@array/protocolList"
            android:entryValues="@array/protocolValues"
            android:key="protocol1"
            android:summary="@string/AnalyzerProtocolSummary"
            android:title="@string/AnalyzerProtocolTitle1" />
        <ListPreference
            android:defaultValue="1"
            android:entries="@array/channelNames"
            android:entryValues="@array/protocolValues"
            android:key="SCL1"
            android:summary="@string/AnalyzerSCLSummary"
            android:title="@string/AnalyzerSCLTitle" />

        <EditTextPreference
            android:defaultValue="9600"
            android:title="@string/AnalyzerBaudTitle"
            android:key="BaudRate1"
            android:summary="@string/AnalyzerBaudSummary"
            android:inputType="number" />
    </PreferenceCategory>

</PreferenceScreen>

所以在一个大屏幕上,我得到预期的结果,我只使用一个 PreferenceFragment 来添加我的 4 个标题。

但是我在 XML 中定义的四个首选项(如 c1analizerprefs.xml)几乎相同,唯一的变化是一个数字(例如:Pref.1、Pref.2、...)所以我想在 Java 中添加它们以便我可以使用a for() 添加 4 个或更多首选项 轻松更改重复次数,因为文本始终相同 我只更改一个数字,所以这样我不需要为每个首选项创建一个 XML 文件,我动态创建它们在爪哇。

如何在 Java 中添加首选项而不是使用 XML 文件?在 PreferenceFragment 中,我只有 addPreferencesFromResource() 或 addPreferencesFromIntent()。有什么方法可以添加首选项对象吗?

4

4 回答 4

6

以防万一有人真的在寻找一些代码......

以下示例从 XML 加载一些标头,然后以编程方式附加到它们。

第一次覆盖onBuildHeaders内的PreferenceActivity

@Override
public void onBuildHeaders(List<Header> target) {
    loadHeadersFromResource(R.xml.preference_headers, target);

    // Add layer as a new settings header
    Header header = new Header();
    header.title = "More Settings";
    header.summary = "Change even more settings";
    header.fragment = SettingsFragment.class.getName();

    Bundle b = new Bundle();
    b.putString("category", "MoreSettings");
    header.fragmentArguments = b;
    target.add(header);
}

然后在PreferenceActivity中覆盖onHeaderClick。请注意,您将标头的 fragmentArguments 传递给片段,以便您可以检测单击了哪个标头(类别):

@Override
public void onHeaderClick(Header header, int position) {    
    this.startPreferencePanel(SettingsFragment.class.getName(), header.fragmentArguments, header.titleRes, header.title, null, 0);
}

然后在您的PreferenceFragment覆盖onCreate

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if (savedInstanceState == null) {
        mCategory = getArguments().getString("category");
    }
    else {
        // Orientation Change
        mCategory = savedInstanceState.getString("category");
    }

    if (mCategory.equals("Map")) {
        // Load the preferences from an XML resource
        addPreferencesFromResource(R.xml.preferences_map);
    }
    if (mCategory.equals("MoreSettings")) {
        // Load the preferences from an XML resource
        PreferenceScreen preferenceScreen = getPreferenceManager().createPreferenceScreen(getActivity());
        // add prefrences using preferenceScreen.addPreference()
        this.setPreferenceScreen(preferenceScreen);
    }
}

如果您想查看预定义标头的 xml。

res/xml/preference_headers.xml

<?xml version="1.0" encoding="utf-8"?>
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
    <header 
        android:fragment="com.appName.fragments.SettingsFragment"
        android:title="@string/pref_category_map_title"
        android:summary="@string/pref_category_map_sum" >
        <!-- key/value pairs can be included as arguments for the fragment. -->
        <extra android:name="category" android:value="Map" />
    </header>
</preference-headers>

res/xml/preferences_map.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <CheckBoxPreference
        android:key="pref_zoomToCurrentLocationOnStart"
        android:title="@string/pref_zoomToCurrentLocationOnStart_title"
        android:summary="@string/pref_zoomToCurrentLocationOnStart_sum"
        android:defaultValue="true" />
    <CheckBoxPreference
        android:key="pref_myLocation"
        android:title="@string/pref_myLocation_title"
        android:summary="@string/pref_myLocation_sum"
        android:defaultValue="true" />
</PreferenceScreen>
于 2014-01-15T15:37:05.493 回答
4

动态添加标题并不容易。正如android文档所述:

Blockquote 典型的实现将使用 loadHeadersFromResource(int, List) 从资源中填充列表。

如果您仍想使用动态解决方案,您可能需要查看 loadHeadersFromResource 的源代码(例如,此处为http://grepcode.com/file/repository.grepcode.com/java/ext/com .google.android/android/4.0.1_r1/android/preference/PreferenceActivity.java#PreferenceActivity.loadHeadersFromResource(int%2Cjava.util.List) )

总结一下,

  1. 你需要创建一个 PreferenceActivity.Header 对象,

  2. 通过设置可以在文档中找到的各种属性来准备使用:http: //developer.android.com/reference/android/preference/PreferenceActivity.Header.html

  3. 最后将创建的标头添加到列表中:(target.add(header);目标是传递给 onBuildHeaders 的参数)

于 2013-04-10T13:42:29.047 回答
1

希望我没有误解你的问题:

getPreferenceScreen().addPreference( preference );
于 2013-04-08T03:10:52.673 回答
0

@goodies4uall 的好回答

我只会添加(因为我还不能编辑帖子)你不需要在 onHeaderClick() 中做任何花哨的事情。

如果您希望在 onBuildHeaders() 之外添加标头,最好的方法是使它们无效并允许 onBuildHeaders() 在下次触发时添加新标头(invalidateHeaders 将导致 onBuildHeaders 再次触发),如下所示:

private boolean flagToAddMyNewHeader = false;

public void someEventFiredThatRequiresANewHeader() {
    flagToAddMyNewHeader = true;
    invalidateHeaders();
}

然后你的 onBuildHeaders:

@Override
public void onBuildHeaders(List<Header> target) {
    loadHeadersFromResource(R.xml.preference_headers, target);

    if (flagToAddMyNewHeader) {
        flagToAddMyNewHeader = false;

        Header header = new Header();
        header.titleRes = R.string.my_new_header_title;
        header.iconRes = R.drawable.my_new_header_icon;
        header.fragment = MyNewHeaderFragment.class.getName();

        Bundle b = new Bundle();
        b.putString("category", "MyNewHeader");
        header.fragmentArguments = b;

        // inserts my new header as the 2nd entry
        target.add(1, header);
    }
}
于 2016-02-20T05:20:34.690 回答