Android:膨胀 PreferenceScreen 时出错

Android: Error inflating PreferenceScreen

我已经看到其他一些与此问题类似的参考资料,但尚未找到解决我的问题的方法。

我曾经使用 android.preference.Preference,但最近为了使用 SeekBarPreference 而转移到了 androidx。

现在,当我尝试给首选项屏幕充气时,出现以下错误:

2021-11-17 20:57:20.623 18270-18270/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.project.test, PID: 18270
android.view.InflateException: Binary XML file line #1: Error inflating class (not found)android.support.v7.preference.PreferenceScreen
    at androidx.preference.PreferenceInflater.createItemFromTag(PreferenceInflater.java:287)
    at androidx.preference.PreferenceInflater.inflate(PreferenceInflater.java:151)
    at androidx.preference.PreferenceInflater.inflate(PreferenceInflater.java:109)
    at androidx.preference.PreferenceManager.inflateFromResource(PreferenceManager.java:216)
    at androidx.preference.PreferenceFragmentCompat.setPreferencesFromResource(PreferenceFragmentCompat.java:377)
    at com.project.test.SettingsFragment.onCreatePreferences(SettingsFragment.java:33)
    at androidx.preference.PreferenceFragmentCompat.onCreate(PreferenceFragmentCompat.java:160)
    at com.project.test.SettingsFragment.onCreate(SettingsFragment.java:25)
    at androidx.fragment.app.Fragment.performCreate(Fragment.java:2684)
    at androidx.fragment.app.FragmentStateManager.create(FragmentStateManager.java:280)
    at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1175)
    at androidx.fragment.app.FragmentTransition.addToFirstInLastOut(FragmentTransition.java:1255)
    at androidx.fragment.app.FragmentTransition.calculateFragments(FragmentTransition.java:1138)
    at androidx.fragment.app.FragmentTransition.startTransitions(FragmentTransition.java:136)
    at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1989)
    at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1947)
    at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1849)
    at androidx.fragment.app.FragmentManager.run(FragmentManager.java:413)
    at android.os.Handler.handleCallback(Handler.java:938)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loopOnce(Looper.java:201)
    at android.os.Looper.loop(Looper.java:288)
    at android.app.ActivityThread.main(ActivityThread.java:7839)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
 Caused by: java.lang.ClassNotFoundException: android.support.v7.preference.PreferenceScreen
    at java.lang.Class.classForName(Native Method)
    at java.lang.Class.forName(Class.java:454)
    at androidx.preference.PreferenceInflater.createItem(PreferenceInflater.java:214)
    at androidx.preference.PreferenceInflater.createItemFromTag(PreferenceInflater.java:277)
    at androidx.preference.PreferenceInflater.inflate(PreferenceInflater.java:151) 
    at androidx.preference.PreferenceInflater.inflate(PreferenceInflater.java:109) 
    at androidx.preference.PreferenceManager.inflateFromResource(PreferenceManager.java:216) 
    at androidx.preference.PreferenceFragmentCompat.setPreferencesFromResource(PreferenceFragmentCompat.java:377) 
    at com.project.test.SettingsFragment.onCreatePreferences(SettingsFragment.java:33) 
    at androidx.preference.PreferenceFragmentCompat.onCreate(PreferenceFragmentCompat.java:160) 
    at com.project.test.SettingsFragment.onCreate(SettingsFragment.java:25) 
    at androidx.fragment.app.Fragment.performCreate(Fragment.java:2684) 
    at androidx.fragment.app.FragmentStateManager.create(FragmentStateManager.java:280) 
    at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1175) 
    at androidx.fragment.app.FragmentTransition.addToFirstInLastOut(FragmentTransition.java:1255) 
    at androidx.fragment.app.FragmentTransition.calculateFragments(FragmentTransition.java:1138) 
    at androidx.fragment.app.FragmentTransition.startTransitions(FragmentTransition.java:136) 
    at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1989) 
    at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1947) 
    at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1849) 
    at androidx.fragment.app.FragmentManager.run(FragmentManager.java:413) 
    at android.os.Handler.handleCallback(Handler.java:938) 
    at android.os.Handler.dispatchMessage(Handler.java:99) 
    at android.os.Looper.loopOnce(Looper.java:201) 
    at android.os.Looper.loop(Looper.java:288) 
    at android.app.ActivityThread.main(ActivityThread.java:7839) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003) 
 Caused by: java.lang.ClassNotFoundException: android.support.v7.preference.PreferenceScreen
    at java.lang.Class.classForName(Native Method) 
    at java.lang.Class.forName(Class.java:454) 
    at androidx.preference.PreferenceInflater.createItem(PreferenceInflater.java:214) 
    at androidx.preference.PreferenceInflater.createItemFromTag(PreferenceInflater.java:277) 
    at androidx.preference.PreferenceInflater.inflate(PreferenceInflater.java:151) 
    at androidx.preference.PreferenceInflater.inflate(PreferenceInflater.java:109) 
    at androidx.preference.PreferenceManager.inflateFromResource(PreferenceManager.java:216) 
    at androidx.preference.PreferenceFragmentCompat.setPreferencesFromResource(PreferenceFragmentCompat.java:377) 
    at com.project.test.SettingsFragment.onCreatePreferences(SettingsFragment.java:33) 
    at androidx.preference.PreferenceFragmentCompat.onCreate(PreferenceFragmentCompat.java:160) 
    at com.project.test.SettingsFragment.onCreate(SettingsFragment.java:25) 
    at androidx.fragment.app.Fragment.performCreate(Fragment.java:2684) 
    at androidx.fragment.app.FragmentStateManager.create(FragmentStateManager.java:280) 
    at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1175) 
    at androidx.fragment.app.FragmentTransition.addToFirstInLastOut(FragmentTransition.java:1255) 
    at androidx.fragment.app.FragmentTransition.calculateFragments(FragmentTransition.java:1138) 
    at androidx.fragment.app.FragmentTransition.startTransitions(FragmentTransition.java:136) 
    at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1989) 
    at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1947) 
    at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1849) 
    at androidx.fragment.app.FragmentManager.run(FragmentManager.java:413) 
    at android.os.Handler.handleCallback(Handler.java:938) 
    at android.os.Handler.dispatchMessage(Handler.java:99) 
    at android.os.Looper.loopOnce(Looper.java:201) 
    at android.os.Looper.loop(Looper.java:288) 
    at android.app.ActivityThread.main(ActivityThread.java:7839) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003) 

我的 SettingsFragment.java 文件的摘录(在 setPreferencesFromResource 行报告了错误):

public class SettingsFragment extends PreferenceFragmentCompat {
Utilities utils = new Utilities();
Context context = ProjectGlobal.getAppContext();
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor settingsEditor = settings.edit()


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

@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
    setPreferencesFromResource(R.xml.pref_general, rootKey);
    Preference pfPermissionsReset = findPreference("permissionsPrompt");
    Preference pfBatterySaving = findPreference("batteryPrompt");
    final SeekBarPreference pfVolumeValue = (SeekBarPreference) findPreference("sbVolume");
    final SwitchPreference pfGlobalVolume = (SwitchPreference) findPreference("chkUseGlobalVolume");

    //init global volume control
    pfVolumeValue.setMax(100);
    pfVolumeValue.setMin(0);

来自我的 pref_general.xml 偏好布局:

<android.support.v7.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

<android.support.v7.preference.PreferenceCategory
    android:summary="App Settings"
    android:title="GENERAL" />
    <android.support.v7.preference.SwitchPreference
        android:key="chkNotificationListener"
        android:summary="This option allows you to disable the app without uninstalling the application. [Default: On]"
        android:title="Notification Listener"
        android:defaultValue="true"
        />

    <android.support.v7.preference.SwitchPreference
        android:key="chkHideBanner"
        android:summary="This option hides the banner notification at the top of the screen. Please note, this may impact the reliability of the application if disabled! [Default: Off]"
        android:title="Hide Banner Notification"
        android:defaultValue="false"
        />
<android.support.v7.preference.Preference android:title="Check Battery Saving"
    android:key="batteryPrompt"
    android:summary="Tap here to check that the app is allowed to run in the background/during startup on your device" />

<android.support.v7.preference.PreferenceCategory
    android:summary="Audio"
    android:title="AUDIO"/>
<android.support.v7.preference.SwitchPreference
    android:key="chkOnlyUseSpeaker"
    android:summary="This option will attempt to play audio alerts from the device loudspeaker only [Default: Off]"
    android:title="Only Use Speaker"
    android:defaultValue="false"
    />
<android.support.v7.preference.SwitchPreference
    android:key="chkUseGlobalVolume"
    android:summary="This option will override any volume settings set in each rule [Default: Off]"
    android:title="Use Global Volume"
    android:defaultValue="false"
    />
<android.support.v7.preference.SeekBarPreference
    android:key="sbVolume"
    android:title="Global Volume"
    android:dependency="chkUseGlobalVolume"
    android:max="100"
    android:defaultValue="50"
    />

/>
<android.support.v7.preference.PreferenceCategory
android:summary="Security"
android:title="SECURITY"/>
    <android.support.v7.preference.Preference android:title="Check Permissions"
        android:key="@string/permissionsPrompt"
        android:summary="Tap here to re-check permissions" />
</android.support.v7.preference.PreferenceScreen>

来自我的 Launcher.java:

public class Launcher extends AppCompatActivity implements SettingsFragment.OnFragmentInteractionListener,RuleFragment.OnFragmentInteractionListener,HelpFragment.OnFragmentInteractionListener {

RuleFragment ruleFragment = new RuleFragment();
SettingsFragment prefsFragment = new SettingsFragment();
HelpFragment helpFragment = new HelpFragment();
Utilities utils = new Utilities();

private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
        = new BottomNavigationView.OnNavigationItemSelectedListener() {

    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case R.id.navigation_home:
                getSupportFragmentManager().beginTransaction().remove(helpFragment).commit();
                getSupportFragmentManager().beginTransaction().remove(prefsFragment).commit();
                getSupportFragmentManager().beginTransaction().replace(R.id.contentFrame,ruleFragment).commit();
                return true;
            case R.id.navigation_settings:
                getSupportFragmentManager().beginTransaction().remove(ruleFragment).commit();
                getSupportFragmentManager().beginTransaction().remove(helpFragment).commit();
                getSupportFragmentManager().beginTransaction().replace(R.id.contentFrame,prefsFragment).commit();
                return true;
            case R.id.navigation_help:
                getSupportFragmentManager().beginTransaction().remove(prefsFragment).commit();
                getSupportFragmentManager().beginTransaction().remove(ruleFragment).commit();
                getSupportFragmentManager().beginTransaction().replace(R.id.contentFrame,helpFragment).commit();
                return true;
        }
        return false;
    }
};
@Override
 public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
    Launcher.context = getApplicationContext();
    Utilities utils = new Utilities();
    
    //initiate home screen
    setContentView(R.layout.main);
    getSupportFragmentManager().beginTransaction().replace(R.id.contentFrame,ruleFragment).commit();
}

我的 main.xml 启动器布局:

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    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">

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:id="@+id/main_coordinator"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        android:layout_above="@+id/navigation"
        app:titleTextColor="@color/Black"
        >

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

        />
    </androidx.coordinatorlayout.widget.CoordinatorLayout>

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/navigation"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:background="?android:attr/windowBackground"

        app:menu="@menu/navigation" />
</RelativeLayout>

设法解决了这个问题。这是因为我没有将pref_general.xml内的android.support.v7.preference更新为androidx.preference.

这样做之后,效果很好!