web-dev-qa-db-fra.com

Android: Kotlin avec Butterknife

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?

40
Rahul

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.
        }

    }) 
87
Nikhil Jadhav

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)
35
AyoGitNg

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.

12
sashk0

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'

voir exemple complet

Lien complet: https://github.com/JetBrains/kotlin-examples/tree/master/gradle/Android-butterknife

10
Pablo Cegarra

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.

4
hetsgandhi

Vous devez simplement ajouter ButterKnife.kt dans votre arbre source à partir du lien suivant:
https://github.com/JakeWharton/kotterknife
Cela a fonctionné pour moi.

3
Vaibhav Jadhav

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

2
Adnan Yousaf

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)
1
Michael Ibrahim

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"
1
dhiku

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

1
Fredy Mederos

À 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
}
0
Sackurise