【问题标题】:Android checkbox disabled but says enabledAndroid复选框已禁用但显示已启用
【发布时间】:2021-09-30 18:09:56
【问题描述】:

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

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

调试步骤:

  • 当我从OnResume 的片段中获得复选框视图的启用状态时,它也会显示true,即使复选框显然已禁用。
  • 当我在另一个视图的 onClickListener 中获得复选框视图的启用状态时,它会显示 false。但是,我的 ViewModel 中的 checkboxEnabled 变量在这里仍然是 true。
  • 如果我启用onViewCreated 中的复选框,它仍然处于禁用状态。
  • 我尝试过在 xml 和 MyViewModel 之间使用不同的绑定,但似乎都不起作用,因此这可能是数据绑定的问题。

如果我没有在代码中的任何位置将 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

    ...
}

【问题讨论】:

    标签: android android-studio android-viewmodel android-checkbox


    【解决方案1】:

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

    另外,我对使用onCreate 和onCreateView 感到困惑,您可以统一它们以保证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()

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

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

    【讨论】:

    • 哇,非常感谢!太多时间调试只是忘记设置binding.viewModel
    • @DanielCJacobs 不客气。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-20
    • 2018-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多