Android 使用 LiveData/OnCheckedChangeListener 来监听变量变化

时间:2024-11-23 07:08:07

 学习笔记

总结:

  • 方法 1:使用 LiveData 是一种更现代和响应式的方式,适用于需要在 UI 更新时自动响应数据变化的场景,特别适合处理状态变化、配置更复杂的业务逻辑时。

  • 方法 2:使用 OnCheckedChangeListener 适合处理控件的值变化(例如 SwitchCheckBox 等)。这种方式比较简单,适合用于基本的监听需求。

方法 1:使用 LiveData 来监听变量变化

1. 定义 LiveData 变量

首先,你需要将 boolean 变量 isBlack 封装到 LiveData 中,LiveData 可以观察数据变化,并自动通知 UI 更新。

步骤:

  1. Activity 中,创建一个 LiveData 来持有 isBlack 的状态。
  2. 使用 Observer 来观察 LiveData,当 isBlack 变化时,更新 ImageView 的背景。

示例代码:

1. 修改 Activity 中的 LiveData 实现:
public class GameActivity extends AppCompatActivity {

    private MutableLiveData<Boolean> isBlackLiveData;  // 用 LiveData 封装 boolean 变量
    private ImageView imageView;  // 需要更新背景的 ImageView

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

        imageView = findViewById(R.id.imageView);  // 获取 ImageView 控件

        // 初始化 LiveData
        isBlackLiveData = new MutableLiveData<>();
        
        // 设置初始值
        isBlackLiveData.setValue(true);

        // 观察 isBlackLiveData 的变化
        isBlackLiveData.observe(this, new Observer<Boolean>() {
            @Override
            public void onChanged(Boolean isBlack) {
                // 当 isBlack 变化时,更新 ImageView 的背景
                if (isBlack) {
                    imageView.setBackgroundResource(R.drawable.black_background);  // 设置黑色背景
                } else {
                    imageView.setBackgroundResource(R.drawable.white_background);  // 设置白色背景
                }
            }
        });

        // 模拟状态变化,切换 isBlack 值
        findViewById(R.id.button_toggle).setOnClickListener(v -> toggleBlackState());
    }

    // 切换 isBlack 状态
    private void toggleBlackState() {
        if (isBlackLiveData.getValue() != null && isBlackLiveData.getValue()) {
            isBlackLiveData.setValue(false);  // 设置为白色
        } else {
            isBlackLiveData.setValue(true);  // 设置为黑色
        }
    }
}
2. activity_game.xml 布局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- ImageView 用于显示背景 -->
    <ImageView
        android:id="@+id/imageView"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_centerInParent="true" />

    <!-- 用于切换状态的按钮 -->
    <Button
        android:id="@+id/button_toggle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Toggle State"
        android:layout_below="@id/imageView"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="20dp" />
</RelativeLayout>

2. 代码解释:

  • LiveDataisBlackLiveData 用来包装 boolean 类型的变量 isBlack,它会自动通知 UI(ActivityFragment)进行更新。

  • Observer:我们使用 Observer 来观察 LiveData 的变化。每次 isBlack 值发生变化时,Observer 会被触发,我们可以在 onChanged 方法中更新 UI,例如更改 ImageView 的背景。

  • 按钮点击事件toggleBlackState() 方法用于模拟 isBlack 变量的状态切换,点击按钮时会改变 isBlack 的值,从而触发 UI 更新。

方法 2:使用 setOnCheckedChangeListener (用于 CheckBoxSwitch

如果你只是想在某些控件(例如 CheckBoxSwitch)的值变化时更新背景,可以直接使用控件的 OnCheckedChangeListener。这种方法不需要 LiveData

public class GameActivity extends AppCompatActivity {

    private boolean isBlack = true;  // 要监听的变量
    private ImageView imageView;  // 需要更新背景的 ImageView

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

        imageView = findViewById(R.id.imageView);  // 获取 ImageView 控件

        // 获取 Switch 控件并设置监听器
        Switch switchToggle = findViewById(R.id.switch_toggle);
        switchToggle.setChecked(isBlack);  // 初始化时根据 isBlack 设置 Switch 的状态

        // 设置监听器
        switchToggle.setOnCheckedChangeListener((buttonView, isChecked) -> {
            // 当 Switch 状态改变时,更新 isBlack 并更新背景
            isBlack = isChecked;
            updateBackgroundBasedOnState(isBlack);
        });
    }

    private void updateBackgroundBasedOnState(boolean isBlack) {
        if (isBlack) {
            imageView.setBackgroundResource(R.drawable.black_background);  // 设置黑色背景
        } else {
            imageView.setBackgroundResource(R.drawable.white_background);  // 设置白色背景
        }
    }
}

布局代码:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- ImageView 用于显示背景 -->
    <ImageView
        android:id="@+id/imageView"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_centerInParent="true" />

    <!-- 用于切换状态的 Switch -->
    <Switch
        android:id="@+id/switch_toggle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Toggle State"
        android:layout_below="@id/imageView"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="20dp" />
</RelativeLayout>