You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过SharedPreference在Options的onCheckedChange中修改MainActivity按钮背景?

解决Android页面间状态同步(不重启Activity)的问题

嘿,我来帮你搞定这个问题!你遇到的空指针异常,核心原因是不能直接在OptionsActivity里获取MainActivity的控件实例——每个Activity都是独立的上下文,当MainActivity不在前台时,它的控件对象已经被销毁或者未初始化,自然会报空指针。SharedPreferences确实是解决这个跨页面状态同步问题的最佳方案,下面我一步步给你讲清楚具体实现:

一、明确要存储的数据

咱们只需要存储一个布尔值,用来标记Switch的勾选状态,比如给这个值起个key叫is_plain_mode_enabled,这样两个页面都能通过这个key读取当前的模式状态。

二、修改OptionsActivity的代码

在Switch的状态变化回调里,咱们只需要做两件事:

  1. 把当前Switch的状态保存到SharedPreferences
  2. 修改OptionsActivity自己的背景(这部分你原来的代码是对的,保留即可)

修改后的OptionsActivity代码:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.options);

    // 初始化SharedPreferences
    SharedPreferences sharedPref = getSharedPreferences("AppSettings", MODE_PRIVATE);
    final SharedPreferences.Editor editor = sharedPref.edit();

    // 初始化Switch,并且设置当前状态为已保存的状态
    final Switch optionPlainColored = findViewById(R.id.switch1);
    boolean isChecked = sharedPref.getBoolean("is_plain_mode_enabled", false);
    optionPlainColored.setChecked(isChecked);
    // 先根据已保存的状态设置当前页面背景
    updateOptionsBackground(isChecked);

    optionPlainColored.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            // 1. 保存状态到SharedPreferences
            editor.putBoolean("is_plain_mode_enabled", isChecked);
            editor.apply(); // 异步保存,不阻塞主线程

            // 2. 更新当前OptionsActivity的背景
            updateOptionsBackground(isChecked);
        }
    });

    Toast.makeText(getApplicationContext(), "Toggling the switch will change background color of the Options and Homescreen to plain colored one", Toast.LENGTH_LONG).show();
}

// 抽成单独的方法,复用代码
private void updateOptionsBackground(boolean isChecked) {
    ImageView background = findViewById(R.id.background);
    if(isChecked){
        background.setImageResource(R.drawable.setoptionsbackgroundcolor2);
    }else{
        background.setImageResource(R.drawable.optionsbackground);
    }
}

三、修改MainActivity的代码

咱们需要让MainActivity能实时感知SharedPreferences的变化,同时在页面启动/从Options返回时,同步最新的状态:

public class MainActivity extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener {

    private SharedPreferences sharedPref;
    private Button attractionsAndArchitecture;
    private Button barsAndRestaurants;
    private Button sportAndRecreations;
    private Button nightlifeAndCulture;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 初始化按钮控件
        attractionsAndArchitecture = findViewById(R.id.attractions_and_architecture);
        barsAndRestaurants = findViewById(R.id.bars_and_restaurants);
        sportAndRecreations = findViewById(R.id.sports_and_recreation);
        nightlifeAndCulture = findViewById(R.id.culture_and_nightlife);

        // 初始化SharedPreferences并设置监听
        sharedPref = getSharedPreferences("AppSettings", MODE_PRIVATE);
        sharedPref.registerOnSharedPreferenceChangeListener(this);

        // 初始化Options按钮跳转逻辑(保留你原来的代码)
        Button options = findViewById(R.id.options);
        options.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intentOptions = new Intent(MainActivity.this, Options.class);
                startActivity(intentOptions);
            }
        });

        // 页面启动时,先根据保存的状态更新按钮背景
        updateButtonsBackground(sharedPref.getBoolean("is_plain_mode_enabled", false));
    }

    @Override
    protected void onResume() {
        super.onResume();
        // 从Options返回时,再次同步状态(保险起见)
        updateButtonsBackground(sharedPref.getBoolean("is_plain_mode_enabled", false));
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 注销监听,避免内存泄漏
        sharedPref.unregisterOnSharedPreferenceChangeListener(this);
    }

    // 监听SharedPreferences变化的回调方法
    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        if("is_plain_mode_enabled".equals(key)){
            boolean isChecked = sharedPreferences.getBoolean(key, false);
            updateButtonsBackground(isChecked);
        }
    }

    // 抽成单独的方法,复用代码
    private void updateButtonsBackground(boolean isChecked) {
        if(isChecked){
            attractionsAndArchitecture.setBackgroundColor(getResources().getColor(R.color.attractionsPlainColor));
            barsAndRestaurants.setBackgroundColor(getResources().getColor(R.color.barsPlainColor));
            sportAndRecreations.setBackgroundColor(getResources().getColor(R.color.sportsPlainColor));
            nightlifeAndCulture.setBackgroundColor(getResources().getColor(R.color.culturePlainColor));
        }else{
            attractionsAndArchitecture.setBackground(getResources().getDrawable(R.drawable.placestovisitbackground));
            barsAndRestaurants.setBackground(getResources().getDrawable(R.drawable.barandrestuarantsbackground));
            sportAndRecreations.setBackground(getResources().getDrawable(R.drawable.sportandrecreationbackground));
            nightlifeAndCulture.setBackground(getResources().getDrawable(R.drawable.nightlifeandculturebackground));
        }
    }
}

四、关键知识点说明

  • SharedPreferences的作用:它是Android轻量级的存储工具,用来保存应用的配置类数据,比如开关状态、用户偏好设置等,所有页面都可以读取和修改这些数据。
  • 为什么用监听:当在OptionsActivity修改了状态,MainActivity能实时收到通知,不用重启页面就能更新UI。
  • 注销监听的重要性:在Activity销毁时一定要注销监听,否则会导致SharedPreferences持有Activity的引用,引发内存泄漏。

这样修改后,你就能实现:勾选Switch时,OptionsActivity背景变化,同时MainActivity的4个按钮背景也会实时更新,完全不需要重启MainActivity~

内容的提问来源于stack exchange,提问作者klavdiym

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:41:36