Android:Kotlin和Butterknife

时间:2017-02-25 06:58:02

标签: android kotlin butterknife

我试图在我的Android应用程序中使用Kotlin和Butterknife。

这是我的build.gradle

dependencies {
    ...
    compile 'com.jakewharton:butterknife:8.0.1'
    kapt 'com.jakewharton:butterknife-compiler:8.0.1'
}

kapt {
    generateStubs = true
}

我还有一个EditText,我希望在更改时使用ButterKnife显示一条消息:

@OnTextChanged(R.id.input)
fun test() {
   toast(1)
}

然而,没有任何反应。我在函数中加了一个断点 - 它甚至都没有执行。

P.S:我听说过kotterknife,但是我看到了example纯粹的Butterknife。

我做错了什么?

11 个答案:

答案 0 :(得分:79)

Kotlin没有必要使用奶油刀。您可以直接使用以下内容:

// app:build.gradle file

<div class="form-group pull-right">
    <input type="text" class="search form-control" placeholder="What you looking for?" id="search">
</div>
<span class="counter pull-right"></span>
<table class="table table-hover table-bordered results" id="table">
    <thead>
        <tr>
            <th>&nbsp;</th>
            <th>Obj ID</th>
            <th>Obj</th>
            <th>Init ID</th>
            <th>Init</th>
        </tr>
        <tr class="warning no-result">
            <td colspan="4"><i class="fa fa-warning"></i> No result</td>
        </tr>
    </thead>
    <tbody>
            <tr data-toggle="collapse" data-target="#demo_1" class="accordion-toggle">
                <td><button class="btn btn-default btn-xs"><span class="glyphicon glyphicon-eye-open"></span></button></td>
                <td scope="row">1</td>
                <td>Obj 1</td>
                <td scope="row">1</td>
                <td>Task 1</td>
            </tr>
                        <tr>
                            <td colspan="12" class="hiddenRow">
                                <div class="accordian-body collapse" id="demo_1">
                                    <table class="table table-striped">
                                        <thead>
                                            <tr style="background-color: darkgrey" id="header_1">
                                                <th>Update ID</th>
                                                <th>Stop Light</th>
                                                <th>Status</th>
                                            </tr>
                                        </thead>
                                        <tbody>
                                                <tr style="background-color: lightgrey" id="update_1">
                                                    <th scope="row">1</th>
                                                    <td>Notes for Update 1</td>
                                                    <td>Other Notes for Update 1</td>
                                                </tr>
                                            <tr>
                                                <td colspan="12" class="hiddenRow">
                                                    <table class="table table-striped">
                                                        <thead>
                                                            <tr style="background-color: darkgrey" id="header_2" >
                                                                <th>Target Quarter</th>
                                                                <th>Added By</th>
                                                                <th>Added On</th>
                                                            </tr>
                                                        </thead>
                                                        <tbody>
                                                                <tr style="background-color: lightgrey" id="target_1">
                                                                    <th scope="row">1</th>
                                                                    <td>User 1</td>
                                                                    <td>1/1/2017</td>
                                                                </tr>
                                                        </tbody>
                                                    </table>
                                                </td>
                                            </tr>
                                        </tbody>
                                    </table>

                                </div>
                            </td>
                        </tr>
    </tbody>
</table>

// xml布局文件

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
}

// MainActivity.kt文件

<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" />

对于onTextChangeListner:

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

    ...
}

答案 1 :(得分:29)

在您的应用级别 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'
}

在您的顶级build.gradle

buildscript {
    ext.kotlin_version = '1.1.3'
    repositories {
        jcenter()
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

<强>活动

@BindView(R.id.toolbar)  @JvmField var toolbar: Toolbar? = null

@BindView(R.id.toolbar) lateinit var toolbar: Toolbar

OnCreate

ButterKnife.bind(this)

答案 2 :(得分:11)

Kotlin创作者在他们的网站上说: Kotlin Android Extensions插件(自动捆绑到Android Studio中的Kotlin插件中)解决了同样的问题:r 使用简洁明了的代码替换findViewById。考虑使用它,除非您已经使用ButterKnife并且不想迁移。

,例如

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

textViewActivity的扩展属性,其类型与activity_main.xml中声明的类型相同。

答案 3 :(得分:10)

在你的gradle中:

compile 'com.jakewharton:butterknife:8.8.0'
kapt "com.jakewharton:butterknife-compiler:8.8.0"

在您的活动中

@BindView(R.id.toolbar)
lateinit var mToolbar: Toolbar

当然,请记住ButterKnife.bind(this)并在app.gradle apply plugin: 'kotlin-kapt'

的顶部应用该插件

Check full example

完整链接:https://github.com/JetBrains/kotlin-examples/tree/master/gradle/android-butterknife

答案 4 :(得分:4)

告别findViewById 或像Butterknife之类的任何库,因为

Kotlin Android扩展插件将生成一些额外的代码,使您可以访问布局XML中的视图,就像它们是具有XML布局定义中使用的ID名称的属性一样。

它也建立一个本地视图缓存。因此,第一次使用属性时,它将执行常规的findViewById。但是下一次,该视图将从缓存中恢复,因此对组件的访问将更快。

请参考docs来通过示例获得更多理解。

答案 5 :(得分:3)

您只需通过以下链接将ButterKnife.kt添加到源树中:
https://github.com/JakeWharton/kotterknife
它对我有用。

答案 6 :(得分:1)

在Project 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
   }
}

在您的应用Build.Gradle中添加此内容。

    //Butterknife
compile "com.jakewharton:butterknife:$butterknife_version"
kapt "com.jakewharton:butterknife-compiler:$butterknife_version"

答案 7 :(得分:1)

您可以实施一些扩展来改善您的观看行为。在常规editText中查看此示例中的“onTextChange”:

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

用法:

m_editText.onTextChange { text, _, _, _ -> 
   m_textView.text = text
}

我投票给kotlin-android-extensions

答案 8 :(得分:1)

Jake Wharton为kotlin创建了一个名为kotterknife的新库: https://github.com/JakeWharton/kotterknife 摇篮:

compile 'com.jakewharton:kotterknife:0.1.0-SNAPSHOT'

查看:

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)

答案 9 :(得分:0)

在Kotlin,实际上没有必要(或)有必要去ButterKnife概念。因为您的活动中的可以直接引用布局文件的视图_id ,如下所述。

<强> 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 (应用)

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

android {
   dependencies {... }
}

kapt {
    generateStubs = true
}

答案 10 :(得分:0)

您可以通过添加以下导入来导入free / res / layout / activity_main.xml布局的所有合成属性:

import kotlinx.android.synthetic.main.activity_main.*

现在,您可以使用id来启动所有视图,而无需启动findbyid