Android 复选框已禁用但显示已启用

Android checkbox disabled but says enabled

我不想为此创建问题,但我不知道发生了什么。

我有一个复选框,其中启用状态绑定到 ViewModel 中的变量 checkboxEnabled。此变量设置为 true,但复选框被禁用。

调试步骤:

如果我没有在代码中的任何位置将 checkboxEnabled 设置为 false,为什么我的复选框会被禁用?可能只是将视图模型与 xml 链接起来的问题吗?

fragment_my.xml:

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MyFragment">
    
    <data>
        <variable
            name="viewModel"
            type=".MyViewModel" />
    </data>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingStart="@dimen/activity_horizontal_margin"
        android:paddingEnd="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin" >

        <CheckBox
            android:id="@+id/checkbox"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:checked="@={viewModel.checkboxChecked}"
            android:enabled="@{viewModel.checkboxEnabled}"
            android:text="This is a checkbox" />

         <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Start"
            android:id="@+id/start_button"
            android:layout_below="@id/checkbox" />

    </RelativeLayout>
</layout>

MyFragment.kt:

class MyFragment() : Fragment() {

    private lateinit var viewModel: MyViewModel

    private var _binding: FragmentMyBinding? = null
    private val binding get() = _binding!!

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        viewModel = ViewModelProvider(this).get(MyViewModel::class.java )
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
        _binding = FragmentMyBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        val checkbox = view.findViewById<CheckBox>(R.id.checkbox)
        checkbox.isEnabled = true // doesn't stay enabled

        startButton = view.findViewById(R.id.start_button)

        startButton.setOnClickListener {
            Log.d("Checkbox enabled", "${checkbox.isEnabled}") // logs `false`
            Log.d("ViewModel checkbox enabled", "${viewModel.checkboxEnabled}") // logs `true`
        }
    }

    override fun onResume() {
        super.onResume()
        val checkbox = activity?.findViewById<CheckBox>(R.id.checkbox)
        Log.d("Resumed", "${checkbox?.isEnabled}") // logs `true`
    }
}

和MyViewModel.kt:

class SensorGnssFragmentViewModel(application: Application) : AndroidViewModel(application) {

    var checkboxChecked = false
    var checkboxEnabled = true

    ...
}

我认为您忘记了将 viewModel 对象传递给具有数据绑定的布局 _binding.viewModel = viewModel

另外,我对使用onCreateonCreateView感到困惑,你可以统一它们以保证viewModel 被初始化并传递给布局。 因此,将 onCreateView 更新为那样..

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
        viewModel = ViewModelProvider(this).get(MyViewModel::class.java )
        _binding = FragmentMyBinding.inflate(inflater, container, false)
        _binding.viewModel = viewModel 
        return binding.root
    }

另一个技巧可以帮助.. 尝试将 viewModel 中的布尔变量替换为 ObservableBoolean 为: val checkboxEnabled : ObservableBoolean = ObservableBoolean()

所以,如果您想更改 check/enable 复选框,只需像那样设置和取消设置可观察对象..

    override fun onResume() {
        super.onResume()
        viewModel.checkboxEnabled.set(true)
    }