J'essaie d'utiliser Kotlin avec Butterknife pour mon Android Application.
Voici mon build.gradle
dependencies {
...
compile 'com.jakewharton:butterknife:8.0.1'
kapt 'com.jakewharton:butterknife-compiler:8.0.1'
}
kapt {
generateStubs = true
}
J'ai aussi un EditText et je veux montrer un message en utilisant ButterKnife quand il est changé:
@OnTextChanged(R.id.input)
fun test() {
toast(1)
}
Cependant, rien ne se passe. Je mets un point d'arrêt dans la fonction - et il n'est même pas exécuté.
P.S: J'ai entendu parler de kotterknife, cependant j'ai vu un exemple avec un pur couteau à beurre.
Qu'est-ce que je fais mal?
Il n'y a pas besoin de couteau à beurre à Kotlin. Vous pouvez directement utiliser les éléments suivants:
// app: fichier build.gradle
apply plugin: 'com.Android.application'
apply plugin: 'kotlin-Android'
apply plugin: 'kotlin-Android-extensions'
apply plugin: 'kotlin-kapt'
Android {
compileSdkVersion 26
buildToolsVersion "26.0.1"
defaultConfig {
applicationId "com.example.nikhiljadhav.myapplication"
minSdkVersion 15
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "Android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-Android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
implementation 'com.Android.support:appcompat-v7:26.0.0'
implementation 'com.Android.support.constraint:constraint-layout:1.0.2'
implementation 'com.Android.support:design:26.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.Android.support.test:runner:1.0.0'
androidTestImplementation 'com.Android.support.test.espresso:espresso-core:3.0.0'
}
kapt {
generateStubs = true
}
// fichier de mise en page xml
<TextView
Android:id="@+id/tvHello"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="Hello World!"
Android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
Android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent"
Android:layout_marginEnd="8dp"
app:layout_constraintStart_toStartOf="parent"
Android:layout_marginStart="8dp" />
<TextView
Android:id="@+id/tvId"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="Hello World!"
Android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
Android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent"
Android:layout_marginEnd="8dp"
app:layout_constraintStart_toStartOf="parent"
Android:layout_marginStart="8dp" />
<EditText
Android:id="@+id/etDemo"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
Android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent"
Android:layout_marginEnd="8dp"
Android:onClick="onClick"
app:layout_constraintStart_toStartOf="parent"
Android:layout_marginStart="8dp" />
// fichier MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
// use the kotlin property
tvHello.text="Hi bla bla"
tvId.text="buubububub"
//set textcolor
tvId.setTextColor(ContextCompat.getColor(this, R.color.colorAccent))
etDemo.hint="nhdodfhfgf"
tvId.setOnClickListener{ view->
onClick(view)
}
fab.setOnClickListener { view ->
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show()
}
}
fun onClick(view: View) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show()
}
...
}
Pour onTextChangeListner:
etText.addTextChangedListener(object : TextWatcher{
override fun afterTextChanged(p0: Editable?) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
})
Dans votre niveau d'application build.gradle
apply plugin: 'kotlin-Android'
kapt {
generateStubs = true
}
dependencies {
compile 'com.jakewharton:butterknife:8.4.0'
kapt 'com.jakewharton:butterknife-compiler:8.4.0'
}
Dans votre niveau supérieur build.gradle
buildscript {
ext.kotlin_version = '1.1.3'
repositories {
jcenter()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
Activité
@BindView(R.id.toolbar) @JvmField var toolbar: Toolbar? = null
o
@BindView(R.id.toolbar) lateinit var toolbar: Toolbar
À l'intérieur OnCreate
ButterKnife.bind(this)
Les créateurs de Kotlin racontent sur leur site que: Kotlin Android Extensions (automatiquement intégré au plug-in Kotlin dans Android Studio) résout le même problème: r en remplaçant findViewById
avec un code concis et simple. Songez à l’utiliser sauf si vous utilisez déjà ButterKnife et ne souhaitez pas migrer.
et par exemple.
// Using R.layout.activity_main from the main source set
import kotlinx.Android.synthetic.main.activity_main.*
class MyActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
textView.setText("Hello, world!")
// Instead of findViewById(R.id.textView) as TextView
}
}
textView
est une propriété d'extension pour Activity
et a le même type que celui déclaré dans activity_main.xml
.
Dans votre note:
compile 'com.jakewharton:butterknife:8.8.0'
kapt "com.jakewharton:butterknife-compiler:8.8.0"
Dans votre activité
@BindView(R.id.toolbar)
lateinit var mToolbar: Toolbar
Bien sûr, rappelez-vous ButterKnife.bind(this)
et appliquez le plug-in au-dessus de votre app.gradle apply plugin: 'kotlin-kapt'
Lien complet: https://github.com/JetBrains/kotlin-examples/tree/master/gradle/Android-butterknife
Dites au revoir à findViewById ou à une bibliothèque telle que Butterknife car,
Kotlin Android Le plug-in Extensions générera du code supplémentaire qui vous permettra d’accéder aux vues dans la mise en forme XML, comme si c’étaient des propriétés portant le nom de l’identifiant que vous avez utilisé dans la définition de mise en page XML.
Il construit également un cache de vue local. Ainsi, la première fois qu'une propriété est utilisée, elle effectuera un findViewById régulier. Mais la prochaine fois, la vue sera récupérée à partir du cache, de sorte que l'accès aux composants sera plus rapide.
Référez-vous à docs pour voir un exemple pour plus de compréhension.
Vous devez simplement ajouter ButterKnife.kt
dans votre arbre source à partir du lien suivant:
https://github.com/JakeWharton/kotterknife
Cela a fonctionné pour moi.
vous pouvez importer toutes les propriétés synthétiques de la disposition free/res/layout/activity_main.xml en ajoutant cette importation:
import kotlinx.Android.synthetic.main.activity_main.*
Maintenant, vous pouvez accéder à toutes les vues en utilisant leur identifiant, pas besoin d'initier findbyid
Jake Wharton a créé une nouvelle bibliothèque pour kotlin appelée kotterknife: https://github.com/JakeWharton/kotterknife Gradle:
compile 'com.jakewharton:kotterknife:0.1.0-SNAPSHOT'
Vue:
val lastName: TextView by bindView(R.id.last_name)
// Optional binding.
val details: TextView? by bindOptionalView(R.id.details)
// List binding.
val nameViews: List<TextView> by bindViews(R.id.first_name, R.id.last_name)
// List binding with optional items being omitted.
val nameViews: List<TextView> by bindOptionalViews(R.id.first_name, R.id.middle_name, R.id.last_name)
Ajoutez ceci dans votre projet Build.gradle
buildscript {
ext.kotlin_version = '1.1.2-4'
ext.butterknife_version = '8.6.0'
repositories {
maven { url 'https://maven.google.com' }
jcenter()
}
dependencies {
classpath 'com.Android.tools.build:gradle:3.0.0-alpha1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "com.jakewharton:butterknife-gradle-plugin:$butterknife_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
Et dans votre application Build.Gradle, ajoutez ceci.
//Butterknife
compile "com.jakewharton:butterknife:$butterknife_version"
kapt "com.jakewharton:butterknife-compiler:$butterknife_version"
Vous pouvez implémenter des extensions pour améliorer le comportement de vos vues. Consultez cet exemple pour "onTextChanged" dans un editText normal:
fun EditText.onTextChange(callback: (text: CharSequence?, start: Int, before: Int, count: Int) -> Unit) {
addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
callback(s, start, before, count)
}
})
}
Usage:
m_editText.onTextChange { text, _, _, _ ->
m_textView.text = text
}
Je vote pour les extensions Android Kotlin
À Kotlin, en réalité, il n’est pas nécessaire (ou nécessaire) d’adopter les concepts ButterKnife. car dans votre activité, vous pouvez vous référer directement à la vue _id du fichier de mise en page comme indiqué ci-dessous.
layout.xml
<Button
Android:id="@+id/btn_prestage"
Android:layout_width="20dp"
Android:layout_height="20dp"
Android:background="@drawable/prestaging_off"/>
Activity.kt
btn_prestage.setBackgroundResource(R.drawable.staging_on)
btn_prestage.setOnClickListener{ view ->
Snackbar.make(view, "My Action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show() }
build.gradle (app)
apply plugin: 'com.Android.application'
apply plugin: 'kotlin-Android'
apply plugin: 'kotlin-Android-extensions'
apply plugin: 'kotlin-kapt'
Android {
dependencies {... }
}
kapt {
generateStubs = true
}