【问题标题】:Smart cast to 'Int' is impossible, because 'mViewModel.counter.value' is a complex expression智能转换为“Int”是不可能的,因为“mViewModel.counter.value”是一个复杂的表达式
【发布时间】:2019-07-06 01:55:16
【问题描述】:

这里是主要活动

class MainActivity : AppCompatActivity() {

    private lateinit var mViewModel: MainActivityVm
    private lateinit var mTv: TextView

    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setSupportActionBar(findViewById(R.id.toolbar))

        mTv = findViewById(R.id.tv)

        mViewModel =
            ViewModelProviders.of(this)
                .get(MainActivityVm::class.java)

        mViewModel.counter.observe(this, Observer<Int> { counter ->
            mTv.setText(counter.toString())
        })

        fab.setOnClickListener { view ->
            if(null != mViewModel.counter.value)
            {
                mViewModel.counter.value++
            }
        }
    }

    // ...
}

当点击 fab 按钮时,我尝试增加数据模型中的计数器

fab.setOnClickListener { view ->
    if(null != mViewModel.counter.value)
    {
        mViewModel.counter.value++
    }
}

但我在mViewModel.counter.value++ 行出现错误

智能转换为 'Int' 是不可能的,因为 'mViewModel.counter.value' 是一个复杂的表达式

错误是什么意思?

这是数据模型

class MainActivityVm : ViewModel() {
    val counter = MutableLiveData<Int>().apply { postValue(0)}
}

编辑

如果我注释掉空检查

fab.setOnClickListener { view ->
    //if(null != mViewModel.counter.value)
    //{
        mViewModel.counter.value++
    //}
}

我得到错误

在 Int 类型的可空接收器上只允许安全 (?.) 或非空断言 (!!.) 调用?

编辑

!!使用空检查

    fab.setOnClickListener { view ->
        if(null != mViewModel.counter.value)
        {
            mViewModel.counter!!.value++
        }
    }

给出初始错误

智能转换为 'Int' 是不可能的,因为 'mViewModel.counter.value' 是一个复杂的表达式

【问题讨论】:

  • 你试试这个mViewModel.counter?.value++
  • @Leo 是的,然后我得到Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type Int?

标签: android kotlin


【解决方案1】:

您只需要使用MutableLiveData#postValue() 方法即可。

另外,最好将功能放在 ViewModel 中。

在 ViewModel 中添加一个方法来增加计数器:

class MainActivityViewModel : ViewModel() {
    val counter = MutableLiveData<Int>().apply { postValue(0)}

    public fun incrementCounter() {
        counter.let {
            val currentVal: Int? = it.value
            currentVal?.let { cur ->
                it.postValue(cur + 1)
            }
        }
    }
}

这也可以写成:

public fun incrementCounter() {
    val currentVal: Int? = counter.value
    if (currentVal != null)
        counter.postValue(currentVal + 1)
}

然后,只需在单击 FAB 时调用该方法:

    fab.setOnClickListener { view ->
        viewModel.incrementCounter()
    }

【讨论】:

  • 那么老式的 null 检查不是线程安全的,但 value?.let 是?
  • @the_prole 这就是我以 kotlin 的方式编写它的方式,但在第二次查看时,它实际上是更短的空检查,所以我在答案中添加了替代实现。主要问题只是使用postValue() 而不是使用++
  • 哦,我以为我必须使用.let 来创建value 的本地副本,以防止另一个线程在空检查之后将value 更改为空,否则Kotlin 不会编译。猜不到。
猜你喜欢
  • 2020-09-22
  • 2018-07-07
  • 1970-01-01
  • 1970-01-01
  • 2017-11-19
  • 1970-01-01
  • 2018-03-23
  • 2016-06-01
相关资源
最近更新 更多