0

Our App will run with 2 Themes. We defined it in themes.xml with AppTheme.White and AppTheme.Black. We know that the error is somewhere in our MainActivity code. If we press the Darkmode Switch in our Settings-Pop-Up the switch will be triggered but the themes won't change. We tried it isolated in our TestApp and the problem isn't the color or layout management. We are pretty sure something went wrong in our setOnCheckedChangeListener method. Thank you for your help! FYI: The App doesn't crash.

This Error appears:

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$2.onMenuItemClick(ToolbarActionBar.java:65)
        at androidx.appcompat.widget.Toolbar$1.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)

This is our MainActivity.class which includes a switch on it's Pop-Up 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);
}

Here our 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>

Also we defined a Utility.java for our sharedPreferences to save the changed Settings:

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);
    }
}

Here also our 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>

Also we defined colors for our Themes in the 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>

Our Theme defined in our manifest.xml:

android:theme="@style/AppTheme.White">
  • I'd guess the problem is a `java.lang.NullPointerException: Attempt to invoke virtual method` somewhere around `at com.example.LulusApp.BaseActivity.onOptionsItemSelected(BaseActivity.java:203)` line 203. – markspace Feb 27 '21 at 18:03
  • Does this answer your question? [What is a NullPointerException, and how do I fix it?](https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – markspace Feb 27 '21 at 18:04
  • @markspace that isn't the proper solution. –  Feb 27 '21 at 18:22

1 Answers1

0

You get this error because you access to the Switch from your activity but it is in the Dialog View for fix that you need just to change this line

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

by this:

Switch darkmodeSwitch = settingsView.findViewById(R.id.darkmode_switch_popup);
Shay Kin
  • 2,539
  • 3
  • 15
  • 22