UmAnusorn
UmAnusorn

Reputation: 11154

How to group the duplicated statement in .apply in Kotlin?

Here is my code. As you can see the body of apply is exactly the same. Is there a better than use extension function?

contentText?.let { 
    contentTextView?.apply { 
        visibility = View.VISIBLE
        text = contentText
    }
}

titleText?.let {
    titleTextView?.apply {
        visibility = View.VISIBLE
        text = titleText
    }
}

Here is my function

private fun setTextAndVisiblity(textView: TextView?, newText: String?): TextView? {
    return textView?.apply {
        visibility = View.VISIBLE
        text = newText
    }
}

This is my code when apply function

contentText?.let {
    setVisibleText(contentTextView, it)
}

titleText?.let {
    setVisibleText(titleTextView, it)
}

Upvotes: 2

Views: 198

Answers (3)

BakaWaii
BakaWaii

Reputation: 6992

I would write the extension function like this:

fun TextView.setVisibleIfTextNotNull(text: CharSequence?) = text?.let {
    visibility = View.VISIBLE
    this.text = it
}

Usage:

contentTextView?.setVisibleIfTextNotNull(contentText)
titleTextView?.setVisibleIfTextNotNull(titleText)

You can either make it as an nested function or private extension function as you like. The name of the function may not be clear enough to clarify what the function does, you may think of a better one.

Upvotes: 2

crgarridos
crgarridos

Reputation: 9273

the cleanest for me is to declare an extension function as:

fun TextView.setVisibleWithText(text: String?){
  text ?: return
  visibility = View.VISIBLE
  setText(text)
}

then calling it as:

myTextView?.setVisibleWithText(myText)

Anyway,remember that an extension functions it just an static util function. This function below:

fun TextView.setVisibleWithText(text: String){
  visibility = View.VISIBLE
  setText(text)
}

Will become something like this in java:

class TextViewKt {
  public static function setVisibleWithText(@NotNull TextView receiver, @NotNull String text){
    receiver.visibility = View.VISIBLE
    receiver.setText(text)
  }
}

And after you can call it as:

theText?.let { theTextView?.setVisibleWithText(it) }

You can always declare a normal funtion as:

  fun setVisibleWithText(textView: TextView, text: String){
      textView.visibility = View.VISIBLE
      textView.text = text
  }

or if you want to make the check inside:

  /***
  * It makes the textview visible if text is not null (it will stay visible if it was visible before)
  **/
  fun setVisibleWithText(textView: TextView, text: String?){
      text ?: return
      textView.visibility = View.VISIBLE
      textView.text = text
  }

Upvotes: 1

Gregor Petrin
Gregor Petrin

Reputation: 2931

An extension function seems like the best choice. If you make the function return this you can use it without apply.

Your other choice would be to create an ordinary function and pass it into also using method references, e.g.

fun setVisibleText(view: View) {  }
titleTextView.also(this::setVisibleText) 

Upvotes: 1

Related Questions