https://kotlinlang.org logo
#android
Title
# android
o

Ofir Bar

02/05/2020, 9:46 AM
Is there a Kotlin way to avoid the code duplication marked here? (Those are syntactic views references)
s

sindrenm

02/05/2020, 9:48 AM
Technically, you could grap all of the container's children, filter to only `TextView`s, loop through those and set the text, but honestly, I'd prefer your current approach. simple smile
👍 2
🍻 1
Something like this could work, I suppose:
Copy code
container.children
  .filterIsInstance<TextView>()
  .forEach {
    it.text = ""
  }
(Not tested, but I seem to remember the APIs are somewhat similar.)
o

Ofir Bar

02/05/2020, 9:56 AM
Duuuude this is so cool i didn’t even knew I can do that
s

sindrenm

02/05/2020, 10:15 AM
It's pretty cool, but be careful, it could lead to less understandable code, and also potentially bugs down the road. Sometimes the most explicit approach is the best. 😉
Also note that
children
is an extension from AndroidX, defined as such:
Copy code
val ViewGroup.children: Sequence<View>
    get() = object : Sequence<View> {
        override fun iterator() = this@children.iterator()
    }
You'll need the core-ktx library to use it (or define it yourself, of course).
🍻 1
m

Mikołaj Karwowski

02/05/2020, 11:02 AM
+1 to being careful with that. It's very surprising when a label that You just added to Your layout disappears suddenly and You can't search for usage of Your view id.
☝️ 3
😮 1
a

Alowaniak

02/05/2020, 12:12 PM
If you want to be explicit but don't want to duplicate the
.text = ""
part you could do:
Copy code
listOf(
  apeFoo,
  apeBar,
  apeFoobar,
  apeEtc
).forEach {
  it.text = ""
}
🎉 8
o

Ofir Bar

02/05/2020, 12:36 PM
@Alowaniak Seems like a solution, but how do I pass the text itself dynamically? Because now every view must have (“”) as text
a

Alowaniak

02/05/2020, 12:55 PM
but how do I pass the text itself dynamically?
Not sure what you mean? If you want different text for each TextView you will have to set the text specifically for them
o

Ofir Bar

02/05/2020, 1:03 PM
I mean I wish I could do something like the following:
Copy code
listOf(
  apeFoo("apeFooText"),
  apeBar("apeBar Text"),
  apeFoobar("Foobar is king text"),
  apeEtc("Etc text")
).forEach {
  it.text = it.textInConstructor
}

// We pass dynamic text yet we eliminate the   constant call to ".text"
m

Mikołaj Karwowski

02/05/2020, 1:34 PM
You're just putting boilerplate without any real benefits that way
Copy code
listOf(
  apeFoo("apeFooText"),
  apeBar("apeBar Text"),
  apeFoobar("Foobar is king text"),
  apeEtc("Etc text")
).forEach {
  it.text = it.textInConstructor
}
does exactly the same as
Copy code
apeFoo.text = "apeFooText"
  apeBar.text = "apeBar Text"
  apeFoobar.text = "Foobar is king text"
  apeEtc.text = "Etc text"
Just by looking at it You should have that 'hell no' feelings in Your guts. Using .text takes less code, is more readable and everybody knows it. It's not bad to have duplication like that in code. Something must duplicate if You do same operation - ex a constructor call in Your implementation. Aggregating views like that makes sense only if You want to do exact same thing on many views. And if You're changing many fields of same object (color, text, text size) with different values You might consider exporting it to a method or a custom view (if it involves more complex logic).
👍 1
🍕 1
And just for the sake of having fun with the language, You could create a method that takes a map of <TextView, String> and use it by passing a created map like that
Copy code
fun setTitles(titlesMap: Map<TextView, String>{
    map.forEach {
        it.key.text = it.value
    }
}

//Then

setTitles(mapOf(
   tvTitle to "I titl",
   tvDesc to "I descript"
))
Or use varargs
Copy code
// fun setTitles(vararg titles: Pair<TextView, String>){
    titles.forEach {
        it.key.text = it.value
    }
}

//Then

setTitles(
   tvTitle to "I titl",
   tvDesc to "I descript"
)
🍻 1
o

Ofir Bar

02/05/2020, 1:52 PM
@Mikołaj Karwowski Thank you, I totally agree Sometimes I overenginner in search for cool ideas as I am a junior developer and love to explore haha
m

Mikołaj Karwowski

02/05/2020, 1:59 PM
Yeah, I still sometimes fall for that too 😅 It's a good thing to explore, with time You'll recognize faster that You're going too far and forgetting what was the initial goal. I actually like the varargs syntax a bit. I don't think I would ever use use it, but it makes me smile a bit. Looks like whole another language and framework when compared to normal Java Android or even Kotlin Android 👾
@Ofir Bar You might want to check that talk out. I ve found it fairly interesting 🙂

https://www.youtube.com/watch?v=YeqGfKmJM_g

o

Ofir Bar

02/05/2020, 2:16 PM
Thank you my friend @Mikołaj Karwowski
🙋‍♂️ 1
h

Hitender Pannu

02/06/2020, 10:11 AM
@sindrenm can we use Constraint Helper from constraint layout also. Some thing like
Copy code
(findViewById<ConstraintHelper>(R.id.textViewGroup))
        .referencedIds.map { findViewById<TextView>(it) }
        .forEach { it.setText("") }
s

sindrenm

02/06/2020, 10:53 AM
Indeed, that should work. But please don't. 😛
🤣 2
h

Hitender Pannu

02/07/2020, 5:00 AM
yeah, it will be really bad 😂
41 Views