Реализация PreferenceFragmentCompat внутри PreferenceFragmentCompat - PullRequest
0 голосов
/ 05 декабря 2018

Вопрос в том, как построить PreferenceFragmentCompat с другими вложенными PreferenceFragmentCompat.

MainActivity:

public class MainActivity extends AppCompatActivity {

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

    getSupportFragmentManager()
        .beginTransaction()
        .replace(android.R.id.content, new PrefsFragment())
        .commit();
}

PrefsFragment:

public class PrefsFragment extends PreferenceFragmentCompat {

@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
    setPreferencesFromResource(R.xml.preferences, rootKey);
}

public static class GeneralPreferenceFragment extends PreferenceFragmentCompat {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
    }

    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        setPreferencesFromResource(R.xml.pref_general, rootKey);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        return super.onOptionsItemSelected(item);
    }
}
...

preferences.xml:

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

<Preference
    app:fragment="com.example.playground.PrefsFragment$GeneralPreferenceFragment"
    android:icon="@drawable/ic_info_black_24dp"
    app:title="@string/pref_header_general"
    app:key="general" />

<Preference
    app:fragment="com.example.playground.PrefsFragment$NotificationPreferenceFragment"
    android:icon="@drawable/ic_notifications_black_24dp"
    app:title="@string/pref_header_notifications"
    app:key="notifications" />

<Preference
    app:fragment="com.example.playground.PrefsFragment$DataSyncPreferenceFragment"
    android:icon="@drawable/ic_sync_black_24dp"
    app:title="@string/pref_header_data_sync"
    app:key="data_sync" />

</PreferenceScreen>

Поэтому, когда я нажимаю на любое предпочтение, ничего не происходит, в то время как я ожидаю, что мой другой PreferenceFragment будет загружен.Я прочитал https://developer.android.com/guide/topics/ui/settings/organize-your-settings,, в котором говорится: Когда пользователь касается предпочтения связанным фрагментом, вызывается метод интерфейса PreferenceFragmentCompat.OnPreferenceStartFragmentCallback.onPreferenceStartFragment ().В этом методе вы должны обрабатывать отображение нового экрана и должны быть реализованы в окружении Activity .

Но я хотел бы реализовать всю логику обработки всех основных фрагментов настроек внутри мой PrefsFragment, а не в родительской активности.Возможно ли это?

Спасибо за ваше время и внимание.

1 Ответ

0 голосов
/ 07 января 2019

Если вы хотите разделить вашу иерархию на несколько экранов , вы можете взглянуть на этот код, взятый непосредственно из примеров Google :
Сначала вы определите root PreferenceScreen таким образом:

<?xml version="1.0" encoding="utf-8"?>

<PreferenceScreen
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <Preference
        app:title="@string/basic_preferences"
        app:summary="Sample preferences using basic attributes"
        app:fragment="com.example.androidx.preference.sample.MainActivity$BasicPreferencesFragment"/>

    <Preference
        app:title="@string/widgets"
        app:summary="Sample preferences with different widgets"
        app:fragment="com.example.androidx.preference.sample.MainActivity$WidgetPreferencesFragment"/>

    <Preference
        app:title="@string/dialogs"
        app:summary="Sample preferences that launch dialogs"
        app:fragment="com.example.androidx.preference.sample.MainActivity$DialogPreferencesFragment"/>

    <Preference
        app:title="@string/advanced_attributes"
        app:summary="Sample preferences with advanced attributes"
        app:fragment="com.example.androidx.preference.sample.MainActivity$AdvancedPreferencesFragment"/>

</PreferenceScreen>

Тогда у вас будет child PreferenceScreen s , например:

<?xml version="1.0" encoding="utf-8"?>

<androidx.preference.PreferenceScreen
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <PreferenceCategory
        app:title="@string/basic_preferences">

        <SwitchPreferenceCompat
            app:key="switch"
            app:title="@string/title_switch_preference"
            app:summary="@string/summary_switch_preference"/>

        <EditTextPreference
            app:key="edittext"
            app:title="@string/title_edittext_preference"
            app:useSimpleSummaryProvider="true"
            app:dialogTitle="@string/dialog_title_edittext_preference"/>

        <ListPreference
            app:key="list"
            app:title="@string/title_list_preference"
            app:useSimpleSummaryProvider="true"
            app:entries="@array/entries"
            app:entryValues="@array/entry_values"
            app:dialogTitle="@string/dialog_title_list_preference"/>

    </PreferenceCategory>

</androidx.preference.PreferenceScreen>

И, наконец,например, Activity с расширением AppCompatActivity с некоторыми внутренними Fragment с расширением PreferenceFragmentCompat:

package com.example.androidx.preference.sample

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat

class MainActivity : AppCompatActivity(),
        PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        supportFragmentManager
                .beginTransaction()
                .replace(R.id.settings, SettingsFragment())
                .commit()
        supportFragmentManager.addOnBackStackChangedListener {
            if (supportFragmentManager.backStackEntryCount == 0) {
                setTitle(R.string.title)
            }
        }
        supportActionBar?.setDisplayHomeAsUpEnabled(true)
    }

    override fun onSupportNavigateUp(): Boolean {
        if (supportFragmentManager.popBackStackImmediate()) {
            return true
        }
        return super.onSupportNavigateUp()
    }

    override fun onPreferenceStartFragment(
            caller: PreferenceFragmentCompat,
            pref: Preference
    ): Boolean {
        // Instantiate the new Fragment
        val args = pref.extras
        val fragment = supportFragmentManager.fragmentFactory.instantiate(
                classLoader,
                pref.fragment,
                args
        ).apply {
            arguments = args
            setTargetFragment(caller, 0)
        }
        // Replace the existing Fragment with the new Fragment
        supportFragmentManager.beginTransaction()
                .replace(R.id.settings, fragment)
                .addToBackStack(null)
                .commit()
        return true
    }

    /**
     * The root preference fragment that displays preferences that link to the other preference
     * fragments below.
     */
    class SettingsFragment : PreferenceFragmentCompat() {
        override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
            setPreferencesFromResource(R.xml.root, rootKey)
        }
    }

    /**
     * A preference fragment that demonstrates commonly used preference attributes.
     */
    class BasicPreferencesFragment : PreferenceFragmentCompat() {
        override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
            setPreferencesFromResource(R.xml.basic_preferences, rootKey)
        }
    }

    /**
     * A preference fragment that demonstrates preferences which contain dynamic widgets.
     */
    class WidgetPreferencesFragment : PreferenceFragmentCompat() {
        override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
            setPreferencesFromResource(R.xml.widgets, rootKey)
        }
    }

    /**
     * A preference fragment that demonstrates preferences that launch a dialog when tapped.
     */
    class DialogPreferencesFragment : PreferenceFragmentCompat() {
        override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
            setPreferencesFromResource(R.xml.dialogs, rootKey)
        }
    }

    /**
     * A preference fragment that demonstrates more advanced attributes and functionality.
     */
    class AdvancedPreferencesFragment : PreferenceFragmentCompat() {
        override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
            setPreferencesFromResource(R.xml.advanced, rootKey)
        }
    }
}
...