首页 > 解决方案 > KOTLIN :如何使用 ViewBinding 在函数中调用视图

问题描述

因此,随着新的 Kotlin、Android Studio 更新,不可能像规范那样使用各自的 ID 调用视图,因此是视图绑定。但是,我一直在尝试使用绑定方法在函数内调用上述视图,但没有成功,因为它一直返回错误

下面是代码:

class JobActivity : AppCompatActivity() {

private val PROGRESS_MAX = 100
private val PROGRESS_START = 0
private val JOB_TIME = 4000 // ms

private lateinit var job: CompletableJob

private lateinit var binding: ActivityJobBinding
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_job)


    binding = ActivityJobBinding.inflate(layoutInflater)
    setContentView(binding.root)
    binding.jobbutton.setOnClickListener {
        if (!::job.isInitialized  ){
            initjob()
        }
    }

}


fun initjob(){
    binding.jobbutton.setText("StartJob #1")
    binding.textView2.setText("")
    job= Job()
    job.invokeOnCompletion {
        it?.message.let {
            var msg = it
            if (msg.isNullOrBlank()){
                msg ="Uknown cancellation Error"
            }
            println("${job} was cancelled. Reason:$msg")
            showtoast(msg)
        }
    }
    binding.progressBar.max= PROGRESS_MAX
    binding.progressBar.progress= PROGRESS_START

}
fun showtoast(text:String){
    Toast.makeText(this@JobActivity, text,Toast.LENGTH_SHORT).show()
}
  }
fun ProgressBar.startJobOrCancel(job: Job) {
if (this.progress > 0) {
    Log.d(TAG, "${job} is already active. Cancelling...")
    resetjob()
} else {
    binding.jobbutton.setText("StartJob #1")
    Log.d(TAG, "coroutine ${this} is activated with job ${job}.")

}
}

错误发生在这里:

在此处输入图像描述

请提供准确的步骤

标签: androidkotlinandroid-viewandroid-viewbinding

解决方案


@GabrielFranciss

嗯,我认为绑定对象在扩展函数之外无法识别,您必须将绑定添加为参数,或者创建一个可以在扩展函数执行和结束时调用的 lambda 函数。

fun ProgressBar.startJobOrCancel(job:Job, jobStarted: () -> Unit ) {
  when {
    this.progress > 0 -> {
      //log
      resetJob()
    }
    else -> {
      jobFinished()
    }
  }
} 

并使用活动/片段中的功能如下:

  private var job = Job()
  private var scope = CoroutineScope(Dispatchers.Default+job)
  /* inside initJob() ... */
  job = scope.launch(){
    binding.progress.startJobOrCancel(job) {
      binding.jobbutton.setText("StartJob #1")
    }
  }

更新(2020-11-17):

onCreate活动内的函数上,删除重复调用setContentView

  ...
  setContentView(R.layout.activity_job) /* remove this if you're using view binding */
  binding = ActivityJobBinding.inflate(layoutInflater)
  setContentView(binding.root)

推荐阅读