主题不是通过按 Switch 设置的。应用程序不会崩溃

Theme is not set by pressing Switch. App doesn't crash

我们的应用程序将 运行 有 2 个主题。我们在 themes.xml 中用 AppTheme.WhiteAppTheme.Black 定义了它。 我们知道错误出在我们的 MainActivity 代码中的某个地方。如果我们在设置弹出窗口中按下 Darkmode 开关,开关将被触发,但主题不会改变。我们在我们的 TestApp 中单独尝试过它,问题不在于颜色或布局管理。我们很确定我们的 setOnCheckedChangeListener 方法出了问题。谢谢您的帮助!仅供参考:应用程序不会崩溃。

出现此错误:

W/System.err: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Switch.setOnCheckedChangeListener(android.widget.CompoundButton$OnCheckedChangeListener)' on a null object reference
        at com.example.LulusApp.BaseActivity.onOptionsItemSelected(BaseActivity.java:203)
        at android.app.Activity.onMenuItemSelected(Activity.java:3543)
        at androidx.fragment.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:383)
        at androidx.appcompat.app.AppCompatActivity.onMenuItemSelected(AppCompatActivity.java:228)
        at androidx.appcompat.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:109)
        at androidx.appcompat.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:109)
        at androidx.appcompat.app.ToolbarActionBar.onMenuItemClick(ToolbarActionBar.java:65)
        at androidx.appcompat.widget.Toolbar.onMenuItemClick(Toolbar.java:207)
        at androidx.appcompat.widget.ActionMenuView$MenuBuilderCallback.onMenuItemSelected(ActionMenuView.java:779)
        at androidx.appcompat.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:834)
        at androidx.appcompat.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:158)

这是我们的 MainActivity.class,其中包含一个弹出式窗口 Window:

    private final static int THEME_WHITE = 1;
    private final static int THEME_BLACK = 2;

public void updateTheme() {
        if (Utility.getTheme(getApplicationContext()) <= THEME_WHITE) {
            setTheme(R.style.AppTheme_White);
        } else if (Utility.getTheme(getApplicationContext()) == THEME_BLACK) {
            setTheme(R.style.AppTheme_Black);
        }
    }
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
    int dot_menu_items = item.getItemId();

    if (dot_menu_items == R.id.action_about) {
        setFragment(aboutFragment);
        return true;
    } else if (dot_menu_items == R.id.action_settings) {
        dialogBuilder = new AlertDialog.Builder(this);
        View settingsView = getLayoutInflater().inflate(R.layout.settings_popup, null);
        settingsView.setClipToOutline(true);
        dialogBuilder.setView(settingsView);
        dialog = dialogBuilder.create();
        dialog.show();

        try {
            Switch darkmodeSwitch = (Switch) findViewById(R.id.darkmode_switch_popup);
            int getcurrentmode = Utility.getTheme(getApplicationContext());
            if (getcurrentmode == 2) {
                darkmodeSwitch.setChecked(true);
            }
            darkmodeSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
                    if (isChecked) {
                        Utility.setTheme(getApplicationContext(), 2);
                    } else {
                        Utility.setTheme(getApplicationContext(), 1);
                    }
                    recreateActivity();
                }

            });
        }catch (Exception e){
            e.printStackTrace();
        }

        return true;
    } else if (dot_menu_items == R.id.action_premium) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

这里是我们的 settings_popup.xml:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    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"
    android:background="?attr/colorPrimary"
    android:layout_gravity="center"
    tools:context=".BaseActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="500dp"
        android:background="#7845ff">

        <Switch
            android:id="@+id/darkmode_switch_popup"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="50px"
            android:background="#032342"
            android:padding="50px"
            android:text="Darkmode"
            android:textColor="?attr/colorPrimary"
            android:textSize="18sp"
            tools:ignore="UseSwitchCompatOrMaterialXml" />

    </LinearLayout>
</FrameLayout>

我们还为 sharedPreferences 定义了一个 Utility.java 来保存更改的设置:

public class Utility {

    public static void setTheme(Context context, int theme) {
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
        prefs.edit().putInt(context.getString(R.string.prefs_theme_key), theme).apply();
    }

    public static int getTheme(Context context) {
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
        return prefs.getInt(context.getString(R.string.prefs_theme_key), 1);
    }
}

这里还有我们的 themes.xml:

<resources>
    <style name="AppTheme.White" parent="Theme.AppCompat.NoActionBar">
        <item name="colorPrimary">@color/primaryColor_white</item>
        <item name="colorPrimaryDark">@color/primaryColorDark_white</item>
        <item name="colorAccent">@color/primaryAccent_white</item>
        <item name="backgroundColor">@color/primaryColorDark_white</item>
        <item name="android:windowAnimationStyle">@style/WindowAnimationTransition</item>
    </style>
    <style name="AppTheme.Black" parent="Theme.AppCompat.NoActionBar">
        <item name="colorPrimary">@color/primaryColor_black</item>
        <item name="colorPrimaryDark">@color/primaryColorDark_black</item>
        <item name="colorAccent">@color/primaryAccent_black</item>
        <item name="backgroundColor">@color/primaryColorDark_black</item>
        <item name="android:windowAnimationStyle">@style/WindowAnimationTransition</item>
    </style>

    <style name="WindowAnimationTransition">
        <item name="android:windowEnterAnimation">@android:anim/fade_in</item>
        <item name="android:windowExitAnimation">@android:anim/fade_out</item>
    </style>
</resources>

我们还在 colors.xml:

中为我们的主题定义了颜色
<?xml version="1.0" encoding="utf-8"?>

<resources>
<color name="primaryColor_white">#6002ee</color>
<color name="primaryColorDark_white">#FFFFFF</color>
<color name="primaryAccent_white">#76FF03</color>

<color name="primaryColor_black">#FFFFFF</color>
<color name="primaryColorDark_black">#6002ee</color>
<color name="primaryAccent_black">#121212</color>

</resources>

我们的主题定义在我们的 manifest.xml:

android:theme="@style/AppTheme.White">

您收到此错误是因为您从 activity 访问了 Switch,但它在对话框视图中用于修复,您只需要更改此行

Switch darkmodeSwitch = findViewById(R.id.darkmode_switch_popup);

通过这个:

Switch darkmodeSwitch = settingsView.findViewById(R.id.darkmode_switch_popup);