๐Ÿ’ป ๊ฐœ๋ฐœ์ฐจ๊ธฐ ๐Ÿฅ‹ feat.Android

๐Ÿ“ฆ Databinding์„ ์“ฐ๋ฉด์„œ - 1 ๋ณธ๋ฌธ

Development/Android

๐Ÿ“ฆ Databinding์„ ์“ฐ๋ฉด์„œ - 1

Android_DevKick 2022. 9. 8. 18:39

Databinding์ด๋ž€!(๋ฐ์ดํ„ฐ ๋ฌถ๊ธฐ?)

→ ์•ˆ๋“œ๋กœ์ด๋“œ์—์„œ์˜ data binding ์ด๋ž€, Android Archictecture Components ์˜ ํ•œ ๋ถ€๋ถ„์œผ๋กœ์„œ

Ui ์š”์†Œ์™€ ๋ฐ์ดํ„ฐ๋ฅผ ํ”„๋กœ๊ทธ๋žจ์  ๋ฐฉ์‹์œผ๋กœ ์—ฐ๊ฒฐํ•˜์ง€ ์•Š๊ณ , ์„ ์–ธ์  ํ˜•์‹์œผ๋กœ ๊ฒฐํ•ฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋งํ•œ๋‹ค.

 

์‰ฝ๊ฒŒ ์„ค๋ช…ํ•˜๋ฉด MVVMํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋ฉด์„œ Activity๋‚˜ Fragment์—์„œ ๋ทฐ ๊ด€๋ จ๋œ ์ฝ”๋“œ๋“ค์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  xml ์ฝ”๋“œ์— ์ง‘์–ด ๋„ฃ๋Š” ๊ฒƒ์„ ๋งํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ๋“ค์„ ViewModel์—์„œ ๊ด€๋ฆฌํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

๋” ๋” ๋” ํ”ผ๋ถ€์— ์™€๋‹ฟ๊ฒŒ ๋งํ•˜์ž๋ฉด Activity๋‚˜ Fragment์—์„œ ๋งŽ์€ ์ฝ”๋“œ๋“ค์„ ์ ์ง€ ์•Š๊ฒŒ ํ•จ์œผ๋กœ์จ ๋ทฐ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ  ๋ณ€ํ™˜์‹œํ‚ค๋Š” ์ฝ”๋“œ๋Š” ViewModel์—์„œ ๊ด€๋ฆฌํ•ด์„œ Activity & Fragment ๋“ค์˜ ์ฝ”๋“œ๋Š” ๋”์šฑ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋งŒ๋“ค๋ฉฐ ๋ถ„๋ฆฌ๋ฅผ ์ œ๋Œ€๋กœ ์‹œ์ผœ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๐Ÿ˜ต ๊ตณ์ด ์™œ ๋ถ„๋ฆฌ๋ฅผ ํ•ด์•ผ๋˜๋‚˜์š”?

→ ๋ผ๊ณ  ๋งํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ์ง€๊ธˆ ๊ฐ„๋‹จํ•œ ์•ฑ์„ ๋งŒ๋“ค๋ฉด ์ƒ๊ด€์—†์ง€๋งŒ ๋‚˜์ค‘์— ๊ธฐ๋Šฅ์ด ๋งŽ์•„์ง€๊ณ  ์ฒ˜๋ฆฌํ•ด์•ผํ•  ๋ฐ์ดํ„ฐ๋“ค์ด ๋งŽ์•„์ง€๋ฉด ๊ด€๋ จ๋œ ์ฝ”๋“œ๋ฅผ ์ฐพ๋Š”๋ฐ ์†Œ๋ชจ๋˜๋Š” ์‹œ๊ฐ„์ด ๋งŽ๊ธฐ ๋•Œ๋ฌธ์— ์ผ์˜ ํšจ์œจ์„ ๋Š˜๋ฆฌ๊ณ  ์œ ์ง€ & ๋ณด์ˆ˜๋ฅผ ๋”์šฑ ํŽธ๋ฆฌํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•จ์ž…๋‹ˆ๋‹ค.

 

๐Ÿค” ๊ฐ„๋‹จํ•œ ์˜ˆ๋ฅผ ๋“ค์–ด ์„ค๋ช…์„ ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค!

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
โ€‹
    <TextView
        android:id="@+id/sample_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
โ€‹
</androidx.constraintlayout.widget.ConstraintLayout>

 

๋ณดํ†ต TextView์˜ ํ…์ŠคํŠธ๋ฅผ ๋ฐ”๊พธ๊ธฐ ์œ„ํ•ด์„  ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฐฉ๋ฒ•์„ ์ผ์„ ๊ฒƒ์ด์ฃ .

// java
TextView textView = findViewById(R.id.sample_text);
textView.setText("์ œ์ด์ฝฅ");
โ€‹
// kotlin
sample_text.setText("์˜ฌ๋ผํ”„");

ํ•˜์ง€๋งŒ data binding์„ ์“ด๋‹ค๋ฉด

<TextView
    android:text="@{viewmodel.userName}" />

์ด์™€ ๊ฐ™์ด ์„ค์ •ํ•˜๋ฉด xml์—์„œ ์ง์ ‘ ๋ณ€๊ฒฝ ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฌผ๋ก  ๊ทธ๋ƒฅ ์ €๋ ‡๊ฒŒ ์“ฐ๋ฉด ์—๋Ÿฌ๊ฐ€ ๋‚˜์„œ ํ•„์š”ํ•œ ๋ถ€๋ถ„์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์œ„์— ์žˆ๋˜ xml ์ฝ”๋“œ๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด ๋ณ€๊ฒฝ ํ•ด์ฃผ๊ณ  ViewModel์„ ํ˜ธ์ถœํ•ด์•ผํ•˜์ฃ 

 

์•„๋ž˜๋ฅผ ๋ณด์‹œ์ฃ 

//////////////////////////////////////////////////////////////////////////
// xml ์ฝ”๋“œ์—์„œ Alert + Enter๋ฅผ ๋ˆ„๋ฅด๋ฉด                                      ///
// convert to data binding layout์ด ๋‚˜์˜ค๋Š”๋ฐ, ๋ˆ„๋ฅด๋ฉด ์ž๋™์œผ๋กœ layout์œผ๋กœ ๋ฌถ์ธ๋‹ค. ///
//////////////////////////////////////////////////////////////////////////
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">
โ€‹
    <data>
        <variable
            name="viewmodel"
            type="com.example.project.ExampleViewModel" />
    </data>
โ€‹
    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".view.workCondition.WorkConditionCarFragment">
โ€‹
        <TextView 
            android:text="@{viewmodel.userName}" />
// ๋ ˆ์ด์•„์›ƒ ๋‚ด์˜ ํ‘œํ˜„์‹์€ "@{}" ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ ์†์„ฑ(attribute properties) ์—์„œ ์ž‘์„ฑ๋œ๋‹ค.
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

 

์ด๊ฒƒ๋งŒ์ด ๋์ด ์•„๋‹™๋‹ˆ๋‹ค.๐Ÿ˜ต(์™œ ๋” ๊ท€์ฐฎ์•„์ง€๋Š” ๊ธฐ๋ถ„์ด ๋“œ๋Š” ๊ฑด ์™œ์ผ๊นŒ?….)

ํ•ด๋‹น xml์„ ์‚ฌ์šฉํ•˜๋Š” Activity๋‚˜ Fragment์—์„œ binding์„ ํ˜ธ์ถœํ•˜๊ณ  ViewModel์„ ์ฃผ์ž…ํ•ด์ค˜์•ผํ•ฉ๋‹ˆ๋‹ค.

class ExampleFragment : Fragment() {
    private lateinit var binding: FragmentExampleBinding
    // ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•œ viewmodel์ž…๋‹ˆ๋‹ค. -> koin
    private val viewModel: WorkConditionViewModel by viewModel()
โ€‹
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = FragmentExampleBinding.inflate(inflater,container,false).apply {
            lifecycleOwner = this@ExampleFragment // ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ์ด Fragment์™€ ์ผ์น˜์‹œํ‚ค๊ฒ ๋‹ค.
            executePendingBindings()
        }
        return binding.root
    }
โ€‹
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding.run {
            this.viewModel = viewModel
        }
    }
}
โ€‹
// ExampleViewModel.kt
class ExampleViewModel: ViewModel() {
    ...
    val userName = MutableLiveData("์ œ์ด์ฝฅ")
    
    ...
}

 

Data Binding์„ ํ”„๋กœ์ ํŠธ์— ๋„์ž…ํ•˜๋ฉด์„œ ๋А๊ผˆ๋˜ ์ ์€

์žฅ์ 

  • Activity์™€ Fragment์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ์˜ ์ค„์ด 90ํ”„๋กœ๊ฐ€ ์‚ฌ๋ผ์กŒ๋‹ค.
  • ๋ถ„๋ฆฌ๊ฐ€ ์ž˜ ๋˜์–ด์žˆ์–ด ์œ ์ง€ ๋ณด์ˆ˜๊ฐ€ ์šฉ์ดํ•˜๋‹ค.
  • ๋ฐ์ดํ„ฐ๋ฅผ ์œ ์ง€ํ•ด์•ผํ•˜๋Š” ๋ถ€๋ถ„์—์„œ ๋‹ค์‹œ ์žฌ์„ค์ •ํ•ด์ฃผ๋Š” ์ฝ”๋“œ๋ฅผ ์‚ฝ์ž…ํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

๋“ฑ๋“ฑ ๋งŽ์€ ์žฅ์ ๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹จ์  ๋˜ํ•œ ์žˆ๊ฒ ์ง€์šฉ?

๋‹จ์ 

  • ViewPager๋‚˜ RecyclerView์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ๋“ค๋„ xml ์•ˆ์œผ๋กœ ๋„ฃ์–ด์•ผํ•˜๋Š”๋ฐ ๋”ฐ๋กœ ์„ค์ •์„ ํ•ด์ค˜์•ผํ•˜๋Š” ๋ถ€๋ถ„๋“ค์ด ๋งŽ๊ธฐ์— Binding Adapter๋ผ๋Š” ๊ธฐ์ˆ ๋„ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค.
  • ๊ฐ€๋ณ๊ฒŒ if ๋ฌธ์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์€๋ฐ ์‚ผํ•ญ ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค.
  • ๊ฐœ๋ฐœ ์†๋„๊ฐ€ ๊ธฐ์กด๋ณด๋‹ค ์กฐ๊ธˆ ๋” ๊ฑธ๋ฆฐ๋‹ค(์•„์ง ์ต์ˆ™ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—,,, ๋‹ค์Œ์—” ๋ฐ”๋€”์ง€๋„?)

๋“ฑ๋“ฑ ์žˆ์ง€๋งŒ ๊ณ„์† ๊ฐœ๋ฐœ์„ ํ•ด๋ณด๋ฉด์„œ ์žฅ์ ์ด ๋” ๋งŽ์€ ๊ฒƒ์œผ๋กœ ๋А๊ปด์ง€๊ณ  ์žˆ๋‹ค.

 

๋‚˜์ค‘์—” Compose๋ฅผ ๋„์ž…ํ•˜๋ฉด ์ด ๊ธฐ๋Šฅ๋„ ๋งŽ์ด ์‚ฌ์šฉ์ด ๋˜์ง€ ์•Š๊ฒ ์ง€๋งŒ ์•„์ง๊นŒ์ง€ Compose๋ฅผ ์ œ๋Œ€๋กœ ์ ์šฉํ•˜๊ธฐ ์ „๊นŒ์ง€๋Š” ์ด ๊ธฐ๋Šฅ์„ ๋งŽ์ด ์‚ฌ์šฉํ•  ๊ฒƒ ๊ฐ™๋‹ค. (์ด๋ฒˆ๋…„๋„ ์•ˆ์—๋Š” Compose ๊ฐœ๋ฐœ ๋ธ”๋กœ๊ทธ๋ฅผ ์“ธ ์˜ˆ์ • ๐Ÿค“)

 

๋‹ค์Œ ํŽธ์€ ์‚ฌ์šฉํ•˜๋ฉด์„œ ๊ฒช์—ˆ๋˜ ์—๋ŸฌโŽ๋‚˜ RecyclerView ๐Ÿ“, ViewPager, Image๐ŸŒ  ๊ด€๋ จํ•ด์„œ ์–ด๋–ป๊ฒŒ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์ ์–ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.