Android片段错误:找不到片段的id 0x7f08009e(com.example.mapplication:id/



我正在尝试创建一个设置菜单(首选屏幕(,当用户单击MainActivity工具栏中的项目时,该菜单将打开。但是,当用户单击MainActivity工具栏中的"Settings"(设置(项目时,会出现以下错误:

   E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.myapplication, PID: 20257
    java.lang.IllegalArgumentException: No view found for id 0x7f08009e (com.example.myapplication:id/preferenceFragment) for fragment MyPreferenceFragment{212e66e (2406d527-5781-4a6b-845c-e7ed6f2b1d9a) id=0x7f08009e}
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:875)
        at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
        at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
        at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)
        at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
        at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
        at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
        at androidx.fragment.app.FragmentManagerImpl$2.run(FragmentManagerImpl.java:150)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7045)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)

以下是MainActivity中的代码,我在其中启动PreferenceScreen:的Activity

// Launch the menus when the user clicks on one of the menu items
override fun onOptionsItemSelected(item: MenuItem): Boolean {
    // Handle presses on the action bar menu items
    when (item.itemId) {
        R.id.settings -> { // User pressed "Settings" button
            try {
                val settingsFragment:Fragment = MyPreferenceFragment() // Create the Settings Fragment
                val transaction:FragmentTransaction = supportFragmentManager.beginTransaction()
                transaction.replace(R.id.preferenceFragment, settingsFragment)
                transaction.addToBackStack(null)
                transaction.commit()
            }
            catch (ex:Exception) {
                println("Exception: " + ex.toString())
            }
            return true
        }
        R.id.about -> { // User pressed "About" button
            println("ABOUT BUTTON CLICKED")
            return true
        }
        R.id.share -> { // User pressed "Share" button
            println("SHARE BUTTON PRESSED")
            return true
        }
    }
    return super.onOptionsItemSelected(item)
}

以下是我的片段(MyPreferenceFragment(代码:

package com.example.myapplication;
import android.os.Bundle;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.SeekBarPreference;
import com.example.myapplication.R;
public class MyPreferenceFragment extends PreferenceFragmentCompat {
    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        addPreferencesFromResource(R.xml.preferences);
        final SeekBarPreference fontSizeSeekBar = (SeekBarPreference) findPreference("font_size");
    }
}

以下是我的片段活动(MyPreferencesActivity.kt(代码:

package com.example.myapplication
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

class MyPreferencesActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_pref)
    }
}

以下是我的AndroidManifest.xml代码(其中包含了Preference活动(:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapplication">
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".MyPreferencesActivity"></activity>
    </application>
</manifest>

以下是我的首选项页面的XML代码(preferences.xml):

<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <androidx.preference.SeekBarPreference
        android:key="font_size"
        android:title="Font Size"
        android:min="12"
        android:max="32"
        android:defaultValue="14" />
</androidx.preference.PreferenceScreen>

以下是我的片段的代码,其中包含首选项页面(activity_pref.xml(:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
    >
    <fragment
        android:id="@+id/preferenceFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.example.myapplication.MyPreferenceFragment" />
</FrameLayout>

我的activity_main.xml布局不包括preferences.xmlactivity_pref.xml

注意:我正在寻找一个答案,该答案必须能够让用户单击MainActivity的工具栏中的项目,并启动包含SeekBarPreference(可以按语法检索,即最终SeekBarPreferences fontSizeSeekBar=(SeekBarPreference(findPreference("font_size"(;(的首选项屏幕。启动片段但无法按语法检索SeekBarPreference的答案将不被接受。

您有两个活动:MainActivity和MyPreferencesActivity。从发布的代码来看,绝对不清楚在哪里以及如何启动后者。您在MyPreferencesActivity中设置了Content,但在MainActivity中替换了fragment。由于容器不是通过MainActivity中的setContent设置的,因此无法找到和替换id/preferenceFragment。

您需要首先启动MyPreferenceActivity,例如通过创建和启动意向,然后在为容器设置内容后替换MyPreferennceActivity类内的视图。

如果需要,您还可以创建一个带有菜单的工具栏,该工具栏特定于您的MyPreferencesActivity,并在此活动中处理OptionsItemSelected。

我在这里详细描述了后一种场景:为每个片段添加一个操作栏

如果用事务替换片段,则需要为容器提供id。这个容器需要在布局中,并且将成为片段视图的父级。

transaction.replace(R.id.preferenceFragment, settingsFragment)

preferenceFragment id是不同布局中的偏好片段的id。如果要将MyPreferenceFragment作为子项添加到主活动中,则需要提供容器id,而不是preferenceFragment

如果您想显示MyPreferencesActivity,您只需要启动此活动,而不需要启动片段事务。MyPreferenceFragment会自动添加到您提供的布局中。

startActivity(Intent(this, MyPreferencesActivity::class.java))

您应该在布局文件中包含preferenceFragment的"活动"中使用此代码:

try {
                val settingsFragment:Fragment = MyPreferenceFragment() // Create the Settings Fragment
                val transaction:FragmentTransaction = supportFragmentManager.beginTransaction()
                transaction.replace(R.id.preferenceFragment, settingsFragment)
                transaction.addToBackStack(null)
                transaction.commit()
            }
            catch (ex:Exception) {
                println("Exception: " + ex.toString())
            }

您得到异常,因为您在活动中使用了transaction.replace(R.id.preferenceFragment, settingsFragment),但其布局文件中没有preferenceFragment!因此,当R.id.settings按钮单击该活动的布局文件中包含preferenceFragment时,您必须启动另一个活动。然后使用以下代码:

transaction.replace(R.id.preferenceFragment, settingsFragment)

因此,请执行以下操作:包com.example.mApplication

  import android.os.Bundle
    import androidx.appcompat.app.AppCompatActivity
class MyPreferencesActivity : AppCompatActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_pref)
    val settingsFragment:Fragment = MyPreferenceFragment()
    getSupportFragmentManager().beginTransaction()
      .replace(R.id.preferenceFragment, settingsFragment)
      .commit()
        }
    }

并将此R.id.settings onclick更改为:

R.id.settings -> { // User pressed "Settings" button
            try {
                val settingActivityIntent = Intent(this, 
                MyPreferencesActivity::class.java)
                startActivity(settingActivityIntent)
            }
            catch (ex:Exception) {
                println("Exception: " + ex.toString())
            }
            return true
        }