Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
453 views
in Technique[技术] by (71.8m points)

Kotlin Android View Binding: findViewById vs Butterknife vs Kotlin Android Extension

I'm trying to figure out the best way to do Android View Binding in Kotlin. It seems like there are a few of options out there:

findViewById

val button: Button by lazy { findViewById<Button>(R.id.button) }

Butterknife

https://github.com/JakeWharton/butterknife

@BindView(R.id.button) lateinit var button: Button

Kotlin Android Extensions

https://kotlinlang.org/docs/tutorials/android-plugin.html

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

I'm pretty familiar with findViewById and Butterknife in java land, but what are the pros and cons of each view binding approach in Kotlin?

Does Kotlin Android Extensions play well with the RecyclerView + ViewHolder pattern?

Also how does Kotlin Android Extensions handle view binding for nested views via include?

ex: For an Activity using activity_main.xml, how would View custom1 be accessed?

activity_main.xml

<...>
    <include layout="@layout/custom" android:id="@+id/custom" />
</>

custom.xml

<...>
    <View android:id="@+id/custom1" ... />
    <View android:id="@+id/custom2" ... />
</>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

kotlin-android-extensions is better for Kotlin. ButterKnife is also good but kotlin-android-extensions is a better and smart choice here.

Reason : Kotlin uses synthetic properties and those are called on demand using caching function(Hence slight fast Activity/Fragment loading) while ButterKnife binds all view at a time on ButterKnife.bind()(that consumes slight more time). With Kotlin you don't even need to use annotation for binding the views.

Yes it also plays good with RecyclerView + ViewHolder pattern, you just need to import kotlinx.android.synthetic.main.layout_main.view.*(if layout_main.xml is Activity/Fragment layout file name).

You do not need to do any extra effort for layout imported using include. Just use id of imported views.

Have a look at following official documentation notes:

Kotlin Android Extensions is a plugin for the Kotlin compiler, and it does two things:

  1. Adds a hidden caching function and a field inside each Kotlin Activity. The method is pretty small so it doesn't increase the size of APK much.
  2. Replaces each synthetic property call with a function call.

    How this works is that when invoking a synthetic property, where the receiver is a Kotlin Activity/Fragment class that is in module sources, the caching function is invoked. For instance, given

class MyActivity : Activity()
fun MyActivity.a() { 
    this.textView.setText(“”)
}

a hidden caching function is generated inside MyActivity, so we can use the caching mechanism.

However in the following case:

fun Activity.b() { 
    this.textView.setText(“”)
}

We wouldn't know if this function would be invoked on only Activities from our sources or on plain Java Activities also. As such, we don’t use caching there, even if MyActivity instance from the previous example is the receiver.

Link to above documentation page

I hope it helps.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...