[Android] BindingAdapter

๐Ÿ’ก ์šฐ์•„ํ•œํ…Œํฌ์ฝ”์Šค๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ DataBinding์—์„œ BindingAdapter๋ฅผ ํ™œ์šฉํ•œ ๊ฒฝํ—˜์„ ๊ธฐ๋กํ•˜์˜€์Šต๋‹ˆ๋‹ค!

 

BindingAdapter

  • Android์˜ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ ๊ธฐ๋Šฅ์—์„œ ์ œ๊ณตํ•˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ, XML ๋ ˆ์ด์•„์›ƒ์—์„œ ์‚ฌ์šฉ์ž ์ •์˜ ์†์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ทฐ์— ๋ฐ์ดํ„ฐ๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ด๋ฅผ ํ†ตํ•ด ๊ธฐ์กด์— ์ œ๊ณต๋˜์ง€ ์•Š๋Š” ์†์„ฑ์„ XML์—์„œ ์ง์ ‘ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๊ณ , ๋ทฐ์˜ ๋กœ์ง๊ณผ UI ์„ค์ •์„ ๋ณด๋‹ค ๊น”๋”ํ•˜๊ฒŒ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐ”์ธ๋”ฉ ์–ด๋Œ‘ํ„ฐ  |  Android Developers

 

๋ฐ”์ธ๋”ฉ ์–ด๋Œ‘ํ„ฐ  |  Android Developers

์ด ํŽ˜์ด์ง€๋Š” Cloud Translation API๋ฅผ ํ†ตํ•ด ๋ฒˆ์—ญ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋ฐ”์ธ๋”ฉ ์–ด๋Œ‘ํ„ฐ ์ปฌ๋ ‰์…˜์„ ์‚ฌ์šฉํ•ด ์ •๋ฆฌํ•˜๊ธฐ ๋‚ด ํ™˜๊ฒฝ์„ค์ •์„ ๊ธฐ์ค€์œผ๋กœ ์ฝ˜ํ…์ธ ๋ฅผ ์ €์žฅํ•˜๊ณ  ๋ถ„๋ฅ˜ํ•˜์„ธ์š”. ๊ฒฐํ•ฉ ์–ด๋Œ‘ํ„ฐ๋Š” ์ ์ ˆํ•œ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ํ˜ธ

developer.android.com

BindingAdapter ์‚ฌ์šฉ

ํ”„๋กœ์ ํŠธ ์„ธํŒ…

  • build.gradle ํŒŒ์ผ์— ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ์„ ํ™œ์„ฑํ™”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
android {
    ...
    viewBinding {
        enabled = true
    }
    dataBinding {
        enabled = true
    }
}

ImageUrl ์†์„ฑ ์„ค์ •

  • BindingAdapter๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ imageUrl ์†์„ฑ์„ ์ฒ˜๋ฆฌํ•  ๋ฉ”์„œ๋“œ๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • ์ด ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด์„œ ImageView์— ์ด๋ฏธ์ง€๋ฅผ ๋กœ๋“œํ•˜๋Š” ์ž‘์—…์„ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค.
import android.widget.ImageView
import androidx.databinding.BindingAdapter
import com.bumptech.glide.Glide

@BindingAdapter("imageUrl")
fun loadImage(view: ImageView, url: String?) {
    url?.let {
        Glide.with(view.context)
            .load(it)
            .into(view)
    }
}

๋ฐ”์ธ๋”ฉ์–ด๋Œ‘ํ„ฐ ํ™œ์šฉ

  • ์„ ์–ธํ•œ ๋ฐ”์ธ๋”ฉ์–ด๋Œ‘ํ„ฐ๋ฅผ XML ๋ ˆ์ด์•„์›ƒ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable
            name="imageUrl"
            type="String" />
    </data>

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:imageUrl="@{imageUrl}" />
</layout>
  • ์ธ์ž๋ฅผ ์ž˜๋ชป ์ „๋‹ฌํ•  ๊ฒฝ์šฐ ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ๋‚  ์ˆ˜ ์žˆ์œผ๋‹ˆ ์กฐ์‹ฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์•กํ‹ฐ๋น„ํ‹ฐ ๋˜๋Š” ํ”„๋ž˜๊ทธ๋จผํŠธ

  • ์•กํ‹ฐ๋น„ํ‹ฐ๋‚˜ ํ”„๋ž˜๊ทธ๋จผํŠธ์—์„œ๋„ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ์„ ํ†ตํ•ด imageUrl ๊ฐ’์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)

        // ์ž„์˜์˜ ์ด๋ฏธ์ง€ URL
        binding.imageUrl = "<https://example.com/sample.jpg>"
    }
}

๋ถ„๊ธฐ์ฒ˜๋ฆฌ์— ํ™œ์šฉ

  • ๋ฐ์ดํ„ฐ๋ฐ”์ธ๋”ฉ์„ ํ™œ์šฉํ•˜๋ฉด XML์—์„œ ๋ณต์žกํ•œ ๋ถ„๊ธฐ์ฒ˜๋ฆฌ๊ฐ€ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ด๋ฅผ ๋ฐ”์ธ๋”ฉ ์–ด๋Œ‘ํ„ฐ์—์„œ ์‰ฝ๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, String์ด๋‚˜ ์ƒ‰์ƒ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
@BindingAdapter("detailViewTypeText")
fun TextView.bindDetailViewTypeText(clubDetailViewType: ClubDetailViewType?) {
    clubDetailViewType ?: return
    val text =
        when (clubDetailViewType) {
            ClubDetailViewType.RECRUITMENT -> context.getString(R.string.club_detail_participate_text)
            ClubDetailViewType.END_RECRUITMENT -> context.getString(R.string.club_detail_un_participate_text)
            ClubDetailViewType.MINE, ClubDetailViewType.PARTICIPATED -> context.getString(R.string.club_detail_mine_text)
        }
    this.text = text
}

์ •๋ฆฌ

  • BindingAdapter๋ฅผ ์‚ฌ์šฉํ•ด ๋ทฐ์˜ ์†์„ฑ์„ ํ™•์žฅํ•˜๊ณ  ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ๊ณผ ํ•จ๊ป˜ ๋ทฐ์™€ ๋ฐ์ดํ„ฐ์˜ ๊ฒฐํ•ฉ์„ ๋”์šฑ ์œ ์—ฐํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ด๋ฅผ ํ†ตํ•ด ์žฌ์‚ฌ์šฉ์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ์œผ๋ฉฐ, UI์™€ ๋กœ์ง์„ ๊น”๋”ํ•˜๊ฒŒ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.