简体   繁体   English

如何在我的 Android 工作室中正确开发暗模式?

[英]How can I correctly to develop the dark mode in my Android studio?

I trying to deploy a switch button for switch the layout to light mode to dark mode, but I got some problem here.我试图部署一个开关按钮来将布局切换到浅色模式到深色模式,但我在这里遇到了一些问题。 When I start the app, it can not auto switch to dark, I have switch to dark mode before I turn off the application before.当我启动应用程序时,它不能自动切换到黑暗,我之前关闭应用程序之前已经切换到黑暗模式。 And when I back to setting page, it will switch to dark mode, but here I got the error.当我回到设置页面时,它会切换到暗模式,但在这里我得到了错误。 The application got into a looping,应用程序陷入循环,

D/TagLifecycle: In the setting darkModeOff event
D/TagLifecycle: In the activity_main onDestroy() event
D/TagLifecycle: In the activity_main onCreate() event
D/TagLifecycle: In the activity_main onStart() event
D/TagLifecycle: In the activity_main onResume() event
D/TagLifecycle: In the activity_main onPause() event
D/TagLifecycle: In the activity_main onStop() event
D/TagLifecycle: In the activity_user_info onCreate() event
D/TagLifecycle: In the activity_setting onCreate() event
D/TagLifecycle: In the setting darkModeOn event
D/TagLifecycle: In the activity_setting onCreate() event
D/TagLifecycle: In the setting darkModeOff event
D/TagLifecycle: In the activity_main onDestroy() event
D/TagLifecycle: In the activity_main onCreate() event
D/TagLifecycle: In the activity_main onStart() event
D/TagLifecycle: In the activity_main onResume() event
D/TagLifecycle: In the activity_main onPause() event
D/TagLifecycle: In the activity_main onStop() event
D/TagLifecycle: In the activity_user_info onCreate() event
D/TagLifecycle: In the activity_setting onCreate() event
D/TagLifecycle: In the setting darkModeOn event
D/TagLifecycle: In the activity_setting onCreate() event
D/TagLifecycle: In the setting darkModeOff event

Here are my setting page code!这是我的设置页面代码!

private Switch darkSwitch;

public static final String MyPREFERENCES= "nightModePrefs";
public static final String KEY_ISNIGHTMODE = "isNightMode";
SharedPreferences sharedPreferences;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_setting);
    Log.d(TAG_LIFECYCLE, "In the activity_setting onCreate() event");

    fbAuth = FirebaseAuth.getInstance();
    fbStore = FirebaseFirestore.getInstance();
    userID = fbAuth.getCurrentUser().getUid();

    sharedPreferences = getSharedPreferences(MyPREFERENCES, Context.MODE_PRIVATE);
    darkSwitch = findViewById(R.id.swDark);

    checkNightModeActivated();

    darkSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if(isChecked) {
                AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
                saveNightModeState(true);
                recreate();
                Log.d(TAG_LIFECYCLE, "In the setting darkModeOn event");
            } else {
                AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
                saveNightModeState(false);
                recreate();
                Log.d(TAG_LIFECYCLE, "In the setting darkModeOff event");
            }
        }

    });

    BottomNavigationView bottomNavigationView = findViewById(R.id.bottom_nav);

    bottomNavigationView.setSelectedItemId(R.id.settingActivity);
    bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
            switch (menuItem.getItemId()) {
                case R.id.mainActivity:
                    startActivity(new Intent(getApplicationContext(),MainActivity.class));
                    overridePendingTransition(0,0);
                    return true;
                case R.id.mapActivity:
                    startActivity(new Intent(getApplicationContext(),MapActivity.class));
                    overridePendingTransition(0,0);
                    return true;
                case R.id.userInfoActivity:
                    startActivity(new Intent(getApplicationContext(),UserInfoActivity.class));
                    overridePendingTransition(0,0);
                    return true;
                case R.id.settingActivity:
                    return true;
            }
            return false;
        }
    });
}
private void saveNightModeState(boolean nightMode) {
    SharedPreferences.Editor editor = sharedPreferences.edit();
    editor.putBoolean(KEY_ISNIGHTMODE, nightMode);
    editor.apply();
}
public void checkNightModeActivated(){
    if (sharedPreferences.getBoolean(KEY_ISNIGHTMODE, false)){
        darkSwitch.setChecked(true);
        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
    } else {
        darkSwitch.setChecked(false);
        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
        }
    }
}

There are quite some things that are wrong here and you can improve on it.这里有很多错误的地方,你可以改进它。 I can tell you the reason why it is looping.我可以告诉你它循环的原因。

Here is where the problem lies:这就是问题所在:

When you first start you are checking up the night mode using this function call checkNightModeActivated();首次启动时,您正在使用此 function 调用checkNightModeActivated();检查夜间模式。

Inside this function里面这个 function

public void checkNightModeActivated(){
    if (sharedPreferences.getBoolean(KEY_ISNIGHTMODE, false)){
        darkSwitch.setChecked(true);
        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
    } else {
        darkSwitch.setChecked(false);
        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
        }
    }
}

You are marking darkSwitch.setChecked(true);您正在标记darkSwitch.setChecked(true); and further you have added an onCheckedListener for this which gets triggered when you mark it as true in here.此外,您为此添加了一个 onCheckedListener,当您在此处将其标记为 true 时会触发它。

Inside the onCheckedListener which as follows:其中onCheckedListener里面如下:

darkSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if(isChecked) {
                AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
                saveNightModeState(true);
                recreate();
                Log.d(TAG_LIFECYCLE, "In the setting darkModeOn event");
            } else {
                AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
                saveNightModeState(false);
                recreate();
                Log.d(TAG_LIFECYCLE, "In the setting darkModeOff event");
            }
        }

    });

You are again recreating the whole activity, from where on checkNightModeActivated();您将再次从checkNightModeActivated(); gets called again and we get looped.再次被调用,我们被循环。

The solution I would recommend for you is to shift the logic of initially checking and applying dark mode to your own personal class which extends the Application() class.我会为您推荐的解决方案是将最初检查和应用暗模式的逻辑转移到您自己的个人 class 中,它扩展了Application() class。 Under it you can place the same logic of checking via SharedPreference and since Application() class remains through-out even if you recreate the activity, you would not get stuck.在它下面,您可以通过 SharedPreference 放置相同的检查逻辑,并且由于Application() class 即使您重新创建活动,您也不会卡住。 Note that you would need to register the said class in Manifest too.请注意,您还需要在 Manifest 中注册上述 class。

Second suggestion would be to have some sort of button to confirm the change instead of directly on checkbox change.第二个建议是使用某种按钮来确认更改,而不是直接更改复选框。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM