如何在FragmentTransaction中为getChildFragmentManager()引用ID

时间:2019-03-17 10:52:52

标签: android android-fragments

我正在尝试使用getChildFragmentManager创建嵌套片段 这是我在SettingsFragment.java代码中的代码。我正在尝试用GeneralPreferencesFragment片段替换它。

SettingsFragment的代码

package com.example.android.memo.Fragments;


import android.annotation.TargetApi;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.preference.PreferenceFragmentCompat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.support.v7.preference.Preference;

import com.example.android.memo.R;

public class SettingsFragment extends PreferenceFragmentCompat implements Preference.OnPreferenceClickListener{


    FragmentTransaction fragmentTransaction;
    private ViewGroup container;

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

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

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        inflater.inflate(R.layout.fragment_settings, container);
        this.container = container;
        fragmentTransaction = getChildFragmentManager().beginTransaction();
        return super.onCreateView(inflater, container, savedInstanceState);

    }

    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        addPreferencesFromResource(R.xml.pref_headers);

        Preference generalPref = (Preference) getPreferenceManager().findPreference(getString(R.string.key_pref_general));

        generalPref.setOnPreferenceClickListener(this);




    }

    @Override
    public boolean onPreferenceClick(Preference preference) {

        if(preference.getKey().equals(getString(R.string.key_pref_general))) {
            GeneralPreferencesFragment generalPreferencesFragment = new GeneralPreferencesFragment();
            fragmentTransaction.replace(R.id.fragment_settings_container, generalPreferencesFragment);
            fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
            fragmentTransaction.addToBackStack(null);
            fragmentTransaction.commit();
        }

        return true;
    }



}

但是,由于找不到R.id.fragment_settings_container

,它不断弹出此错误消息。
java.lang.IllegalArgumentException: No view found for id 0x7f09005c (com.example.android.memo:id/fragment_main_container) for fragment GeneralPreferencesFragment{9017d3f #0 id=0x7f09005c}
                                                                          at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1422)
                                                                          at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1759)
                                                                          at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1827)
                                                                          at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:797)
                                                                          at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2596)
                                                                          at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2383)
                                                                          at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2338)
                                                                          at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2245)
                                                                          at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:703)
                                                                          at android.os.Handler.handleCallback(Handler.java:815)
                                                                          at android.os.Handler.dispatchMessage(Handler.java:104)
                                                                          at android.os.Looper.loop(Looper.java:207)
                                                                          at android.app.ActivityThread.main(ActivityThread.java:5763)
                                                                          at java.lang.reflect.Method.invoke(Native Method)
                                                                          at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:888)
                                                                          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:749)

我看过其他一些解决方案,它说我引用的id必须是setContentView()中放置的布局的子级。但是,由于这是一个片段,因此我正在使用inflater.inflate(R.layout.fragment_settings, container); 我引用的ID是fragment_settings文件的子级,因此我不确定自己在做什么错。 这是 fragment_settings.xml 布局文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.android.memo.Fragments.SettingsFragment">

<FrameLayout
    android:id="@+id/fragment_settings_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

</FrameLayout>

</RelativeLayout>

一般偏好代码

package com.example.android.memo.Fragments;


import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.preference.CheckBoxPreference;
import android.support.v7.preference.EditTextPreference;
import android.support.v7.preference.ListPreference;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceFragmentCompat;
import android.support.v7.preference.PreferenceScreen;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.example.android.memo.R;


/**
 * A simple {@link Fragment} subclass.
 */
public class GeneralPreferencesFragment extends PreferenceFragmentCompat implements
        SharedPreferences.OnSharedPreferenceChangeListener {

    private void setPreferenceSummary(Preference preference, Object value) {
        String stringValue = value.toString();
        String key = preference.getKey();

        if (preference instanceof ListPreference) {
            /* For list preferences, look up the correct display value in */
            /* the preference's 'entries' list (since they have separate labels/values). */
            ListPreference listPreference = (ListPreference) preference;
            int prefIndex = listPreference.findIndexOfValue(stringValue);
            if (prefIndex >= 0) {
                preference.setSummary(listPreference.getEntries()[prefIndex]);
            }
        } else {
            // For other preferences, set the summary to the value's simple string representation.
            preference.setSummary(stringValue);
        }
    }

    @Override
    public void onCreatePreferences(Bundle bundle, String s) {
        /* Add 'general' preferences, defined in the XML file */
        addPreferencesFromResource(R.xml.pref_general);

        SharedPreferences sharedPreferences = getPreferenceScreen().getSharedPreferences();
        PreferenceScreen prefScreen = getPreferenceScreen();
        int count = prefScreen.getPreferenceCount();
        for (int i = 0; i < count; i++) {
            Preference p = prefScreen.getPreference(i);
            if (!(p instanceof CheckBoxPreference)) {
                String value = sharedPreferences.getString(p.getKey(), "");
                setPreferenceSummary(p, value);
            }
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        /* Unregister the preference change listener */
        getPreferenceScreen().getSharedPreferences()
                .unregisterOnSharedPreferenceChangeListener(this);
    }

    @Override
    public void onStart() {
        super.onStart();
        /* Register the preference change listener */
        getPreferenceScreen().getSharedPreferences()
                .registerOnSharedPreferenceChangeListener(this);
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        Preference preference = findPreference(key);
        if (null != preference) {
            if (!(preference instanceof CheckBoxPreference)) {
                setPreferenceSummary(preference, sharedPreferences.getString(key, ""));
            }
        }
    }
}

先谢谢您。

1 个答案:

答案 0 :(得分:0)

问题:您正在通过PreferenceFragmentCompat使用自定义布局,因此必须使用另一种方法使它协同工作。

解决方案:您可以按照以下步骤操作

第1步:转到style.xml,然后添加以下行

styles.xml

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <!-- Add this line -->
    <item name="preferenceTheme">@style/CustomPreferenceTheme</item>
</style>

<!-- Add this line -->
<style name="CustomPreferenceTheme" parent="@style/PreferenceThemeOverlay.v14.Material">
    <item name="preferenceFragmentCompatStyle">@style/CustomPreferenceFragmentCompatStyle</item>
</style>

<!-- Add this line -->
<style name="CustomPreferenceFragmentCompatStyle" parent="@style/PreferenceFragment.Material">
    <item name="android:layout">@layout/fragment_settings</item>
</style>

第2步:更改fragment_settings布局

fragment_settings.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">

    <FrameLayout
            android:id="@android:id/list_container"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

    </FrameLayout>
</RelativeLayout>

第3步:修改SettingsFragment

SettingsFragment.java

public class SettingsFragment extends PreferenceFragmentCompat implements Preference.OnPreferenceClickListener {

    private ViewGroup container;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        this.container = container;
        return super.onCreateView(inflater, container, savedInstanceState);
    }

    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        addPreferencesFromResource(R.xml.pref_headers);
        Preference generalPref = getPreferenceManager().findPreference(getString(R.string.key_pref_general));
        generalPref.setOnPreferenceClickListener(this);
    }

    @Override
    public boolean onPreferenceClick(Preference preference) {
        if (preference.getKey().equals(getString(R.string.key_pref_general))) {
            GeneralPreferencesFragment generalPreferencesFragment = new GeneralPreferencesFragment();

            getChildFragmentManager().beginTransaction()
                    .replace(android.R.id.list_container, generalPreferencesFragment)
                    .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
                    .addToBackStack(null)
                    .commit();
        }

        return true;
    }
}