我正在尝试使用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, ""));
}
}
}
}
先谢谢您。
答案 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;
}
}