首页 > 解决方案 > 以编程方式填充 PreferenceFragment XML 已包含的子 PreferenceScreen

问题描述

对不起,奇怪的标题。

我想以编程方式将 a 添加到此文件中已经存在PreferenceCategory的我的一个(我的裁剪版本):PreferenceScreenspreferences.xml

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

    <!-- Monitored Zones -->
    <PreferenceScreen
        android:key="pref_ps_mz"
        android:title="Zones surveillées"
        android:summary="Pour gérer vos zones surveillées"
        android:icon="@drawable/ic_pref_mz">

        <SwitchPreference
            android:key="pref_mz_sw_mzDisplayFilter"
            android:title="Afficher"
            android:summary="Les zones surveillées seront affichées en rouge sur votre carte"
            android:defaultValue="true" />

        <PreferenceScreen
            android:key="pref_mz_removeAll"
            android:title="Toutes les supprimer"
            android:summary="Pour supprimer toutes vos Zones Surveillées" />
    </PreferenceScreen>

    <!-- Notifications -->
    <PreferenceScreen
        android:key="pref_ps_notif"
        android:title="Notifications"
        android:summary="Les notifications vous sont envoyées par notre serveur selon vos préférences"
        android:icon="@drawable/ic_pref_notifs">

        <SwitchPreference
            android:key="pref_notif_sw_mirrorAlertFilters"
            android:title="Appliquer mes filtres d'alertes"
            android:summary="Pour ne recevoir des notifications qu'en lien avec les alertes que vous affichez sur la carte (ces préférences se retrouvent dans la catégorie « Filtres d'alertes »)"
            android:defaultValue="false"/>
    </PreferenceScreen>

</PreferenceScreen>

更具体地说,PreferenceScreenwithandroid:key="pref_ps_mz"是我想添加的一个PreferenceCategory。这PreferenceCategory应该出现在之后android:key="pref_mz_removeAll",并且我应该能够PreferenceScreen根据可用于单独删除的对象数量以编程方式使用对象填充它。我假设一旦完成,我就可以轻松地将“onClickListeners”添加到每个PreferenceScreen对象。

这是我的(裁剪的)SettingsPrefFragment.java文件:

public class SettingsPrefFragment extends PreferenceFragment {

    private SharedPreferences sharedPref;


    public SettingsPrefFragment() {
        // Required empty public constructor
    }


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);

        sharedPref = PreferenceManager.getDefaultSharedPreferences(getActivity());

        FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();

        /*
        Keys hierarchy:
            pref_ps_mz
                pref_mz_sw_mzDisplayFilter
                pref_mz_removeAll
            pref_ps_notif
                pref_notif_sw_mirrorAlertFilters
                pref_notif_sw_noise
                pref_notif_sw_block
         */

        /*
            Monitored Zones
         */

        Preference mzPref = findPreference("pref_ps_mz");
        mzPref.setEnabled(false);

        // Enabling access only if authenticated
        if(user != null) {
            mzPref.setEnabled(true);
        }

        // Managing monitored zones
        findPreference("pref_mz_sw_mzDisplayFilter").setOnPreferenceClickListener(preference -> {
            PinController.PinPreferences.showMonitoredZones = sharedPref.getBoolean("pref_mz_sw_mzDisplayFilter", true);
            return true;
        });

        // TODO: DISABLE if the user has 0 MZ
        // Removing all MonitoredZones
        findPreference("pref_mz_removeAll").setOnPreferenceClickListener(preference -> {

            AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity());
            alertDialogBuilder.setMessage("Voulez-vous vraiment effacer toutes vos Zones Surveillées?");

            alertDialogBuilder.setNegativeButton("Annuler", (dialog, which) -> dialog.cancel()); // rien faire
            alertDialogBuilder.setPositiveButton("Oui", (arg0, arg1) -> {
                MainActivity.myMapDisplay.getZoneController().clearAllZones(user);
            });

            AlertDialog alertDialog = alertDialogBuilder.create();
            alertDialog.show();

            return true;
        });

        // TODO: Programmatically populate a PreferenceCategory with MonitoredZonesWrapper's MonitoredZones



        /*
            Notifications
         */

        Preference notifPref = findPreference("pref_ps_notif");
        notifPref.setEnabled(false);

        // Enabling access only if authenticated
        if(user != null) {
            notifPref.setEnabled(true);
        }
    }
}

我已经尝试过这个解决方案(添加到onCreate()Fragment 中),但这还不够,我无法弄清楚如何使用它来做我希望的事情:

    PreferenceScreen screen = getPreferenceManager().createPreferenceScreen(getActivity());

    PreferenceCategory category = new PreferenceCategory(getActivity());
    category.setTitle("category name");

    screen.addPreference(category);

    CheckBoxPreference checkBoxPref = new CheckBoxPreference(getActivity());
    checkBoxPref.setTitle("title");
    checkBoxPref.setSummary("summary");
    checkBoxPref.setChecked(true);

    category.addPreference(checkBoxPref);
    setPreferenceScreen(screen);

    addPreferencesFromResource(R.xml.preferences);

它只能PreferenceCategory在根的最顶部添加 a PreferenceScreen。我需要能够填充子 PreferenceScreen 的底部。

非常感谢您!

标签: androidandroid-preferencespreferenceactivity

解决方案


在添加类别之前添加 PreferencesFromResource,以便以编程方式添加的项目放置在从 xml 加载的首选项之后。

addPreferencesFromResource(R.xml.preferences); //Placement matters!

PreferenceScreen screen = (PreferenceScreen)findPreference("pref_ps_mz");
PreferenceCategory category = new PreferenceCategory(getActivity());
category.setTitle("category name");

screen.addPreference(category);

CheckBoxPreference checkBoxPref = new CheckBoxPreference(getActivity());
checkBoxPref.setTitle("title");
checkBoxPref.setSummary("summary");
checkBoxPref.setChecked(true);

category.addPreference(checkBoxPref);
//setPreferenceScreen(screen); //Unnecessary as long as the above code is in the onCreate section

推荐阅读