3
votes

KOTLIN: Comment déclarer une vue dans une fonction à l'aide de ViewBinding

Donc, avec la nouvelle mise à jour du studio Android Kotlin, il est impossible d'appeler des vues en utilisant leur ID respectif comme la norme, d'où la liaison de vues. Cependant, j'ai essayé d'appeler ladite vue dans une fonction en utilisant la méthode de liaison sans succès car elle continue de renvoyer une erreur

ci-dessous est le 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}.")

}
}

l'erreur se produit ici:

entrez la description de l'image ici

veuillez fournir des étapes précises


0 commentaires

3 Réponses :


3
votes

@GabrielFranciss

mmm, je pense que l'objet de liaison n'est pas reconnu en dehors de la fonction d'extension, vous devez ajouter la liaison en tant que paramètre, ou créer une fonction lambda qui pourrait être appelée lorsque la fonction d'extension s'exécute et se termine.

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

Et en utilisant la fonction dans l'activité / le fragment comme suit:

  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")
    }
  }

Mise à jour (17/11/2020):

Sur la fonction onCreate à l'intérieur de l'activité, supprimez l'appel dupliqué à setContentView :

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


5 commentaires

@Marlom Lopez une question, comment l'appellerons-nous avec la liaison, j'ai honnêtement essayé votre approche mais cela ne fonctionne pas.


@marlon lopez, veuillez montrer comment vous ajoutez la liaison en tant que paramètre


@SaginiChan la liaison n'est pas ajoutée en tant que paramètre, je veux dire, dans l'extrait de code, j'ai utilisé une fonction lambda comme paramètre (alias, une fonction d'ordre élevé), avec cela, la fonction est appelée à l'intérieur de la fonction qui exécute le Job. Dans l'écran de l'interface utilisateur, l'utilisation de la fonction d'ordre supérieur peut être similaire à l'utilisation de l'interface anonyme dans les méthodes java. (suite ...)


@SaginiChan (suite ...) vous pouvez consulter la documentation de kotlin pour l'utilisation des lambdas comme paramètre de fonction ( kotlinlang.org/docs/reference/lambdas.html ) ...


@GabrielFranciss ... l'objet de liaison est utilisé dans l'implémentation de la fonction d'ordre supérieur, qui est passée en paramètre dans la fonction d'extension. J'ai utilisé le même code que vous avez partagé pour l'utilisation de la fonction. donc, c'est facile à comprendre. gardez à l'esprit quelque chose, le travail est exécuté comme une coroutine, vous pouvez donc vérifier que la fonction qui a été exécutée après la fonction d'extension est appelée dans la portée de l'interface utilisateur



1
votes

Vous devez supprimer cette ligne:

welcomeMessage.text = "Hello Kotlin!"

et en cas de non utilisation de ViewBinding, vous pouvez utiliser les extensions Kotlin Android en ajoutant ce plugin dans Gradle:

 android:id="@+id/welcomeMessage"

et il suffit d'appeler view par son identifiant! par exemple pour TextView avec cette ligne de code:

 apply plugin: 'kotlin-android-extensions'

vous pouvez facilement appeler:

setContentView(R.layout.activity_job)


1 commentaires

mmm, je pense que l'utilisation d'importations synthétiques n'est pas un moyen recommandé de résoudre ce problème. Veuillez vérifier ce lien pour plus de détails -> reddit.com/r/androiddev/comments/ala9p2/...



1
votes

Tout d'abord, supprimez la méthode OnCreate qu'elle est redondante et inutile:

plugins {

id 'kotlin-android'
id 'kotlin-android-extensions'

Vous pouvez décider de revenir à la méthode initiale Kotlin d'appeler les vues dans l'activité par leur ID respectif en ajoutant cette ligne (ps: c'est la façon mise à jour d'ajouter des plugins dans la nouvelle version kotlin 1.4.0:

setContentView(R.layout.activity_job)

}

en utilisant cette méthode, il est possible de le faire de la manière originale mais un petit avertissement, vous pouvez être susceptible d'appeler des opérations nulles.


0 commentaires