Reputation: 35
So with the new Kotlin, Android studio update, it is impossible to call views using their respective ID like the norm, hence viewbinding. However, I have been trying to call the said view inside a function using the binding method to no success as it keeps returning an error
below is the code:
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}.")
}
}
the error occurs here:
please provide precise steps
Upvotes: 3
Views: 1855
Reputation: 301
1.First thing's first, remove the OnCreate method its redundant and unnecessary:
setContentView(R.layout.activity_job)
2.You can decide to go back to the initial Kotlin method of calling views in the activity by their respective ID by adding this line (ps: this is the updated way of adding plugins in the new kotlin version 1.4.0:
plugins {
id 'kotlin-android'
id 'kotlin-android-extensions'
}
using this method, it is possible to do it the original way but slight warning,, you may be susceptible to calling null operations.
Upvotes: 1
Reputation: 480
@GabrielFranciss
mmm, i think the binding object its not recognized outside the extension function, you must add the binding as a parameter, or, create a lambda function that could be invoked when the extension function executes and concludes.
fun ProgressBar.startJobOrCancel(job:Job, jobStarted: () -> Unit ) {
when {
this.progress > 0 -> {
//log
resetJob()
}
else -> {
jobFinished()
}
}
}
And using the function in the activity/fragment as follows:
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")
}
}
On the onCreate
function inside the activity, remove the duplicated call to setContentView
:
...
setContentView(R.layout.activity_job) /* remove this if you're using view binding */
binding = ActivityJobBinding.inflate(layoutInflater)
setContentView(binding.root)
Upvotes: 3
Reputation: 329
You should remove this line:
setContentView(R.layout.activity_job)
and in case of not using ViewBinding, you can use Kotlin Android Extensions by adding this plugin in Gradle :
apply plugin: 'kotlin-android-extensions'
and just call view by its id! for example for TextView with this line of code:
android:id="@+id/welcomeMessage"
you can easily call :
welcomeMessage.text = "Hello Kotlin!"
Upvotes: 1