A question about the buttons on Android Kotlin

Hi
I generate a random number between 1 and 9
And I have 9 buttons in the Android App wrriten in kotlin
How can I add the generated number to Ui buttons?
That means my buttons start with btn_1 and end with btn_9
how can i connect the generated number btn_randomnumber that is between 1 to 9 and convert it to Button

You must use arrays / lists instead of multiples variables.

When you have a list of buttons, you can access directly to a random button

val randomNumber = Random().nextInt(9);
val randomButton = buttons[randomNumber];
1 Like

And if you are using a library like Butterknife it is pretty trivial to have butterknife fill in an array of the buttons for you. See the View Lists section at Butter Knife

1 Like

Just curious… is there any big advantage to using Butterknife over Kotlin Android Extensions?

The only way I know to have Butterknife make the array/list for you is to list all of the IDs:

val views: List<Button> by bindViews( 
        R.id.btn_1, 
        R.id.btn_2, 
        R.id.btn_3, 
        R.id.btn_4, 
        R.id.btn_5, 
        R.id.btn_6, 
        R.id.btn_7, 
        R.id.btn_8, 
        R.id.btn_9 )

With Kotlin Android Extensions, you still have to list them, but it’s much more concise:

val views = listOf(btn_1, btn_2, btn_3, btn_4, btn_5, btn_6, btn_7, btn_8, btn_9)

I know there are other things Butterknife can do (like enabling or disabling sets of view at once) but most of those features come out naturally almost as concise in idiomatic Kotlin anyway.

Just wondering if there’s something I’m missing…

1 Like

Actually that’s a 3rd option, Kotterknife, also by Jake Wharton.

As far as conciseness, a static import of R.id.* would make it more concise.

Any of them would work. I haven’t used the Android extensions, because for a long time I couldn’t get them to work and I had used Butterknife for years. I have actually contributed to Kotterknife.

Butterknife may be slightly more complicated in that you have a generated class to invoke to do the binding while Kotterknife and KAE are just hiding the findViewById.

1 Like

Butterknife is a great library—I used it a lot when doing Java dev. Since switching to Kotlin (which is fairly recent) I’ve found that Kotlin Android Extensions seem to cover all of the major use cases from Butterknife, so I didn’t bother with Butterknife when switching to Kotlin (well, with Kotterknife…)

The problem with a static import of R.id.* is that it brings in everything (even from other activities) which really pollutes the namespace for for a complex app. There could also be problem if different activities use the same ID for views of different types (I’ve seen things like R.id.content being used for a ConstraintLayout in one place and a RelativeLayout in another, in the same app).

With Kotlin Android Extensions, you’re only bringing in the symbols for the particular layout (or layouts) that you need, and they come in with the correct types (correct View subclasses). As someone who really likes type safety, I find the Kotlin Android Extensions appealing in that sense.

What I really wish for is a way to “tag” views in some way in the XML so that all views in a given layout with the same tag come in as a list. I don’t mean the current android:tag approach; I mean something functionally more like css classes. It would be super awesome to be able to have <Button tag='foo bar' ... /> and then be able to just write something like foo.forEach { it.isEnabled = false }. This would open the door to extension functions on List<View> so you could write foo.disableAll() for example. If there were implemented the same was a Kotlin Android Extensions, the list would automatically pick up the correct type based on the tagged views. Ah well, one can dream…

1 Like

Hi
Thanks for all the friends who answered my question.
I will review and give you the result from this section