在首选项设置屏幕中找不到片段 ID 的视图
No view found for id for fragment in Preference setting screen
在我的应用程序中,我使用 DraverLayout 作为主要 activity,其中包含片段作为 navigationView 的一部分。
但是对于设置,我使用包含 SettingFragment 的 SettingActivity。当我尝试从设置屏幕打开子屏幕时出现问题:
"java.lang.IllegalArgumentException: 找不到片段 NotificationMenuFragment{1fe50ef} (618cc8dc-6287-4830-b9a1-0e9b2d1d1827) id= id 0x7f09014e (com.example.tipcollector:id/settings_container) 的视图0x7f09014e}”。哪里做错了,我该如何解决?我将不胜感激任何帮助或信息!
SettingActivity.java
package com.example.tipcollector;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import android.os.Bundle;
import com.example.tipcollector.Notification.NotificationMenuFragment;
public class SettingsActivity extends AppCompatActivity implements PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
private Toolbar toolbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_setting);
toolbar = findViewById(R.id.mainToolbar);
setSupportActionBar(toolbar);
if(findViewById(R.id.settings_container)!=null){
if(savedInstanceState!=null)
return;
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.settings_container, new SettingsFragment()).commit();
}
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
@Override
public boolean onPreferenceStartFragment(PreferenceFragmentCompat caller, Preference pref) {
final Bundle args = pref.getExtras();
final Fragment fragment = getSupportFragmentManager().getFragmentFactory().instantiate(
getClassLoader(),
pref.getFragment());
fragment.setArguments(args);
fragment.setTargetFragment(caller,0);
getSupportFragmentManager().beginTransaction()
.replace(R.id.settings_container, fragment)
.addToBackStack(null)
.commit();
return true;
}
}
这是我的 SettingsFragment
package com.example.tipcollector;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.text.InputType;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.preference.EditTextPreference;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceManager;
import com.example.tipcollector.Notification.NotificationMenuFragment;
import database.DataBaseHelper;
public class SettingsFragment extends PreferenceFragmentCompat implements PreferenceManager.OnPreferenceTreeClickListener {
public static final String PREF_HOURLY_RATE = "hourly_rate_key";
public static final String PREF_CURRENCY = "currencies";
public static final String PREF_NOTIFICATION = "notifications";
private SharedPreferences.OnSharedPreferenceChangeListener preferenceChangeListener;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public boolean onPreferenceTreeClick(Preference preference) {
String key = preference.getKey();
if ("clear_all_key".equals(key)) {}
if(PREF_NOTIFICATION.equals(key)){
getChildFragmentManager().beginTransaction().replace(R.id.settings_container,new NotificationMenuFragment()).commit();
}
return true;
}
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.preferencesscreen,rootKey);
preferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if(key.equals(PREF_HOURLY_RATE)){
EditTextPreference hourlyRatePref = findPreference(key);
hourlyRatePref.setSummary(sharedPreferences.getString(key,""));
}else if(key.equals(PREF_CURRENCY)){
ListPreference currencyPref = findPreference(key);
currencyPref.setSummary(sharedPreferences.getString(key,""));
}
}
};
}
和 xml 文件。这是首选项屏幕(SettingFragment 的布局)
<?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">
<PreferenceCategory
android:title="@string/setting_general"
/>
<ListPreference
android:entryValues="@array/currencies"
android:entries="@array/currencies"
app:title="@string/select_currency"
app:key="currencies"
android:icon="@drawable/ic_money_black"
android:defaultValue="PLN"/>
<EditTextPreference
android:summary="@string/settings_general_hourly_rate"
android:title="@string/your_hourly_rate"
app:key="hourly_rate_key"
android:icon="@drawable/ic_business_center_black_24dp"
/>
<PreferenceCategory
android:title="@string/data_settings"/>
<Preference
android:title="@string/clear_all_database"
app:key="clear_all_key"
android:summary="@string/clear_all_data_message"
android:icon="@drawable/ic_delete_forever_black_24dp"/>
<PreferenceCategory
android:title="Notification"/>
<Preference
android:title="Notification"
app:key="notification"
android:icon="@drawable/ic_notifications_black_24dp"/>
</PreferenceScreen>
这里是SettingActivity
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SettingsActivity"
android:orientation="vertical">
<include
layout="@layout/main_toolbar"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/settings_container"/>
</LinearLayout>
要在您的 preferencesscreen.xml
中完成的更改
<Preference
android:title="Notification"
app:key="notification"
android:icon="@drawable/ic_notifications_black_24dp"
app:fragment="com.example.tipcollector.Notification.NotificationMenuFragment" />
此外,从您的 SettingsFragment 中删除此方法
@Override
public boolean onPreferenceTreeClick(Preference preference) {
String key = preference.getKey();
if ("clear_all_key".equals(key)) {}
if(PREF_NOTIFICATION.equals(key)){
getChildFragmentManager().beginTransaction().replace(R.id.settings_container,new NotificationMenuFragment()).commit();
}
return true;
}
您不需要这个,因为 preferenceClick 将由 xml
中的这个标签处理
app:fragment="com.example.tipcollector.Notification.NotificationMenuFragment"
在我的应用程序中,我使用 DraverLayout 作为主要 activity,其中包含片段作为 navigationView 的一部分。
但是对于设置,我使用包含 SettingFragment 的 SettingActivity。当我尝试从设置屏幕打开子屏幕时出现问题:
"java.lang.IllegalArgumentException: 找不到片段 NotificationMenuFragment{1fe50ef} (618cc8dc-6287-4830-b9a1-0e9b2d1d1827) id= id 0x7f09014e (com.example.tipcollector:id/settings_container) 的视图0x7f09014e}”。哪里做错了,我该如何解决?我将不胜感激任何帮助或信息!
SettingActivity.java
package com.example.tipcollector;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import android.os.Bundle;
import com.example.tipcollector.Notification.NotificationMenuFragment;
public class SettingsActivity extends AppCompatActivity implements PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
private Toolbar toolbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_setting);
toolbar = findViewById(R.id.mainToolbar);
setSupportActionBar(toolbar);
if(findViewById(R.id.settings_container)!=null){
if(savedInstanceState!=null)
return;
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.settings_container, new SettingsFragment()).commit();
}
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
@Override
public boolean onPreferenceStartFragment(PreferenceFragmentCompat caller, Preference pref) {
final Bundle args = pref.getExtras();
final Fragment fragment = getSupportFragmentManager().getFragmentFactory().instantiate(
getClassLoader(),
pref.getFragment());
fragment.setArguments(args);
fragment.setTargetFragment(caller,0);
getSupportFragmentManager().beginTransaction()
.replace(R.id.settings_container, fragment)
.addToBackStack(null)
.commit();
return true;
}
}
这是我的 SettingsFragment
package com.example.tipcollector;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.text.InputType;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.preference.EditTextPreference;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceManager;
import com.example.tipcollector.Notification.NotificationMenuFragment;
import database.DataBaseHelper;
public class SettingsFragment extends PreferenceFragmentCompat implements PreferenceManager.OnPreferenceTreeClickListener {
public static final String PREF_HOURLY_RATE = "hourly_rate_key";
public static final String PREF_CURRENCY = "currencies";
public static final String PREF_NOTIFICATION = "notifications";
private SharedPreferences.OnSharedPreferenceChangeListener preferenceChangeListener;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public boolean onPreferenceTreeClick(Preference preference) {
String key = preference.getKey();
if ("clear_all_key".equals(key)) {}
if(PREF_NOTIFICATION.equals(key)){
getChildFragmentManager().beginTransaction().replace(R.id.settings_container,new NotificationMenuFragment()).commit();
}
return true;
}
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.preferencesscreen,rootKey);
preferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if(key.equals(PREF_HOURLY_RATE)){
EditTextPreference hourlyRatePref = findPreference(key);
hourlyRatePref.setSummary(sharedPreferences.getString(key,""));
}else if(key.equals(PREF_CURRENCY)){
ListPreference currencyPref = findPreference(key);
currencyPref.setSummary(sharedPreferences.getString(key,""));
}
}
};
}
和 xml 文件。这是首选项屏幕(SettingFragment 的布局)
<?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">
<PreferenceCategory
android:title="@string/setting_general"
/>
<ListPreference
android:entryValues="@array/currencies"
android:entries="@array/currencies"
app:title="@string/select_currency"
app:key="currencies"
android:icon="@drawable/ic_money_black"
android:defaultValue="PLN"/>
<EditTextPreference
android:summary="@string/settings_general_hourly_rate"
android:title="@string/your_hourly_rate"
app:key="hourly_rate_key"
android:icon="@drawable/ic_business_center_black_24dp"
/>
<PreferenceCategory
android:title="@string/data_settings"/>
<Preference
android:title="@string/clear_all_database"
app:key="clear_all_key"
android:summary="@string/clear_all_data_message"
android:icon="@drawable/ic_delete_forever_black_24dp"/>
<PreferenceCategory
android:title="Notification"/>
<Preference
android:title="Notification"
app:key="notification"
android:icon="@drawable/ic_notifications_black_24dp"/>
</PreferenceScreen>
这里是SettingActivity
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SettingsActivity"
android:orientation="vertical">
<include
layout="@layout/main_toolbar"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/settings_container"/>
</LinearLayout>
要在您的 preferencesscreen.xml
中完成的更改<Preference
android:title="Notification"
app:key="notification"
android:icon="@drawable/ic_notifications_black_24dp"
app:fragment="com.example.tipcollector.Notification.NotificationMenuFragment" />
此外,从您的 SettingsFragment 中删除此方法
@Override
public boolean onPreferenceTreeClick(Preference preference) {
String key = preference.getKey();
if ("clear_all_key".equals(key)) {}
if(PREF_NOTIFICATION.equals(key)){
getChildFragmentManager().beginTransaction().replace(R.id.settings_container,new NotificationMenuFragment()).commit();
}
return true;
}
您不需要这个,因为 preferenceClick 将由 xml
中的这个标签处理app:fragment="com.example.tipcollector.Notification.NotificationMenuFragment"