์ด๋ฒ ํฌ์คํ ์์๋ ViewBinding์ ์ข ๋ ๋ฏ์ด๋ณด๊ณ ์ฌ๋ฌ ๋ทฐ์ ์ ์ฉ๋ ์์ผ๋ณด๋ ๋ด์ฉ์ ๋ค๋ฃจ์ด ๋ณด๋ ค๊ณ ํฉ๋๋ค.

- ์ฌ์ค ํ์ ์์๋ ํ์๋๋ ViewBinding์ ์ตํ ์จ์๊ณ ์ต์ํ๊ณ ๋น์ฐํ View์ ๋ด์ฉ์ ๊ฐ์ ธ์ค๊ธฐ ์ํด์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด๊ธฐ ๋๋ฌธ์ ๊ธฐ์ ์ ์ผ๋ก ํ๊ตฌ๋ฅผ ํด๋ณผ ์๊ฐ์ ์์๋๋ฐ์.
- ์ด๋ฒ์ ์ฌ๋ฌ ์ด์๋ค์ ๊ฒช์ผ๋ฉด์ ๊ฒฝํ์ ์์กดํ๋ ์ฝ๋ฉ์ด ๊ต์ฅํ ์ํํ๊ณ ์ค์ ์ ์ธ ์
๋ฌด ์ฒ๋ฆฌ ๋ฅ๋ ฅ์ ์ ํ์ํค๋ ๊ฒ์ ๊ฒฝํํ๋ฉด์ ๋ค์ ์๋ก ์ ์ธ ๋ฌธ์ ์ ์ง์คํ๋ ์๊ฐ์ ๊ฐ์ ธ๋ณด๊ฒ ๋์์ต๋๋ค.
๊ทธ๋์ ์ฌ๋ฌ ๋ฌธ์๋ค์ ๋ณด๊ณ ์ฝ๋์๋ ๋ น์ฌ๋ณด๋ฉด์ ์ด ๊ธ์ ์์ฑํ๊ณ ์๋ค์. ์ญ์ ๊ณต๋ถ๋ ๋ฏธ๋ฆฌ๋ฏธ๋ฆฌ ๊ผผ๊ผผํ๊ฒ,,,
gradle(:app) ํ์ผ์์ viewBinding ํ์ฑํ
android {
buildFeatures {
viewBinding = true
}
}
xml : result_profile.xml
xml ํ์ผ ๋ช
์์ ์์ฑ๋ binding ํด๋์ค์ ์ด๋ฆ : ResultProfileBinding
๋ํ ๋ชจ๋ Binding ํด๋์ค์๋ ์์ํ๋ ๋ ์ด์์ ํ์ผ์ ๋ฃจํธ ๋ทฐ์ ์ง์ ์ฐธ์กฐ๋ฅผ ์ ๊ณตํ๋ getRoot() (kotlin : root) ๋ฉ์๋๋ ํฌํจ์
๋๋ค.
<LinearLayout ... >
<TextView android:id="@+id/name" />
<ImageView android:cropToPadding="true" />
<Button android:id="@+id/button"
android:background="@drawable/rounded_button" />
</LinearLayout>
Activity์์ View์ ๊ฒฐํฉ์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ
onCreate() ๋ฉ์๋์ ViewBinding์ ์ธ์คํด์ค๋ฅผ ์ค์ ํฉ๋๋ค.
- ์์ฑ๋ binding ํด๋์ค์ ํฌํจ๋ ์ ์ inflate() ๋ฉ์๋๋ฅผ ํธ์ถ -> Activity์์ ์ฌ์ฉํ ํด๋์ค ์ธ์คํด์ค ์์ฑ
- getRoot() or Kotlin ์์ฑ ๋ฌธ๋ฒ .root ๋ฅผ ํตํด RootView๋ฅผ ์ฐธ์กฐํ๋ค.
- RootView๋ฅผ setContentView()์ ์ ๋ฌํ์ฌ ํ๋ฉด์ ํ์ฑ ๋ทฐ๋ก ์ ์ธํ๋ค.
private lateinit var binding: ResultProfileBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ResultProfileBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
}
AppCompatActivity.java ๋ด๋ถ์ setContentView() ๋ฉ์๋
@Override
public void setContentView(View view) {
initViewTreeOwners();
getDelegate().setContentView(view);
}
Fragment ์์ View ๊ฒฐํฉ์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ
onCreateView() ๋ฉ์๋์ ViewBinding์ ์ธ์คํด์ค๋ฅผ ์ค์ ํฉ๋๋ค.
- ์์ฑ๋ binding ํด๋์ค์ ํฌํจ๋ ์ ์ inflate() ๋ฉ์๋๋ฅผ ํธ์ถ -> Fragment์์ ์ฌ์ฉํ ํด๋์ค ์ธ์คํด์ค ์์ฑ
- getRoot() or Kotlin ์์ฑ ๋ฌธ๋ฒ .root๋ฅผ ํตํด RootView๋ฅผ ์ฐธ์กฐํ๋ค.
- RootView๋ฅผ onCreateView()์ ์ ๋ฌํ์ฌ ํ๋ฉด์ ํ์ฑ ๋ทฐ๋ก ์ ์ธํ๋ค.
private var _binding: ResultProfileBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = ResultProfileBinding.inflate(inflater, container, false)
val view = binding.root
return view
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
์ฌ๊ธฐ๊น์ง๊ฐ ๊ธฐ๋ณธ์ ์ผ๋ก Android Developer์์ ์ ๊ณตํ๋ Guide์ ์ฝ๋๋ค์
๋๋ค. ์ด๋ฐ ๊ฒ์ฒ๋ผ ViewBinding์ ๊ตฌ์ฑํ ์ ์๋๋ฐ, ๊ทธ๋ฌ๋ฉด Activity, Fragment ๋ง๋ค๋ง๋ค ๊ฐ๊ฐ์ ViewBinding ์ฝ๋๊ฐ ์๊ฒจ๋๋ ์ํฉ์ ๋ง์ฃผํ๊ฒ ๋ฉ๋๋ค.
๊ทธ๋์ ๋ณดํต์ ์ด๋ฅผ code base ์์ ๋ค๋ฃฐ ์ ์๋๋ก ๋ถ๋ชจ ํด๋์ค๋ฅผ ํ๋ ๋ง๋ค์ด์ ์ฌ์ฉํ๊ณค ํฉ๋๋ค. BaseActivity.kt , BaseFragment.kt ์ด๋ฐ ์์ผ๋ก ๋ฒ ์ด์ค ํด๋์ค๋ฅผ ๋ง๋ค๊ณ ์ด ์์์ binding ๋ฐ ๊ธฐํ ๋ถ๋ชจ ํด๋์ค์ ์ญํ ๋ก ๊ฐ์ ธ๊ฐ ์ ์๋ ๊ฒ๋ค์ ๋ถ๋ฆฌํฉ๋๋ค.
์ด๋ ๊ฒ ์๋์ ์ฝ๋์ฒ๋ผ BaseActivity๋ฅผ ๊ตฌํํ๊ณ ์ด๋ฅผ ์์๋ฐ๋ ํน์ Activity ์ฝ๋์์ Binding ์ฒ๋ฆฌ๋ฅผ ํด์ฃผ๊ณ ์์ต๋๋ค.
์ด๋, setContentView()๋ DataBindingUtilํด๋์ค์ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๊ฒ ๋ฉ๋๋ค.
DataBindingUtil ํด๋์ค๋ Binding ํ์
์ ์ฌ์ ์ ์ ์ ์์ ๋, DataBindingUtil์ ์ฌ์ฉํด์ Binding ํด๋์ค๋ฅผ ์์ฑํ ์ ์๋ ํด๋์ค ์
๋๋ค.
BaseActivity
abstract class BaseActivity<Binding : ViewDataBinding>(private val layout: Int) : AppCompatActivity() {
protected lateinit var binding: Binding
protected lateinit var callback: OnBackPressedCallback
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, layout)
binding.lifecycleOwner = this
}
}
@SuppressLint("CustomSplashScreen")
@AndroidEntryPoint
class SplashActivity : BaseActivity<ActivitySplashBinding>(R.layout.activity_splash) {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
...
}
BaseFragment
abstract class BaseFragment<Binding : ViewDataBinding>(private val layout: Int) : Fragment() {
protected lateinit var binding: Binding
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DataBindingUtil.inflate(inflater, layout, container, false)
binding.lifecycleOwner = viewLifecycleOwner
return binding.root
}
....
}
@AndroidEntryPoint
class MainFragment : BaseFragment<FragmentMainBinding>(R.layout.fragment_main) {
....
}
๊ทผ๋ฐ ์ฌ์ค ์ด๋ ๊ฒ ๋๋ฉด ViewBinding ๋ณด๋ค๋ DataBinding์ผ๋ก ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ด ๋๊ฒ ๋ค์. ์ด๋ ๊ฒ DataBinding์ ์ฌ์ฉํ ๋์๋ xml ์ฝ๋ ๋ด ์ต์์ ํ๊ทธ๋ฅผ <layout> </layout>์ผ๋ก ์ง์ ํด ์ฃผ์ด์ผ ํฉ๋๋ค. ๊ทธ๋ฌ๋ฉด ViewBinding๊ณผ DataBinding์ด ๋ค๋ฅธ ๊ฑฐ๋,,๋ผ๊ณ ํ๊ธฐ์๋ viewBinding์ด DataBinding์ ๋ถ๋ถ์งํฉ์ด๋ผ ์ด๊ฑธ ๋ฐ์ง๋ ์๋ฏธ๊ฐ ์์๊น ์ถ๊ธฐ๋ ํฉ๋๋ค.
์ฝ๊ฐ View ๊ฐ์ฒดํ ๋ฐฉ๋ฒ ์ค findViewById()๋ฅผ ์ฐ์ง ์๊ธฐ ์ํด์๋ ViewBinding์ ๊ถ์ฅํ๋ ๋ฏํ๊ณ ์ข ๋ ๋์ ์ผ๋ก ์ฌ์ฉํ๊ณ ๋จ์ํ View ๋ฟ๋ง์ด ์๋ ๊ธฐ๋ฅ์ ์ฌ์ฉ์ ์ํด์๋ DataBinding์ ์ด๋ฐ ๋๋์ผ๋ก ๊ถ์ฅํ๋ ๊ฒ ๊ฐ์ต๋๋ค.
์ ๋ ์ค๋ฌด ํ๋ก์ ํธ์์ DataBinding, ViewBinding์ ํผ์ฉํด์ ์ฌ์ฉํ๊ณ ์๋๋ฐ์. ํผ์ฉ ์์ฒด์๋ ๋ฌธ์ ๊ฐ ์์ง๋ง ์ข ๋ ๋์ ๋ฐฉ๋ฒ์ด ์๋ค๋ฉด ๊ฐ์ ์ ํด๋ด์งํ๊ธฐ๋ ํ ๊ฒ ๊ฐ๋ค์. ํ ๐

'๐ป ๊ฐ๋ฐ์ ์ด์ผ๊ธฐ > ์๋๋ก์ด๋ ์ฝ์ง๊ธฐ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
์์กด์ฑ ์ฃผ์ ์ Hilt๋ก, ๋คํธ์ํฌ ํต์ ์ Retrofit์ผ๋ก (0) | 2024.06.25 |
---|---|
Android ์์ ์งธ๊น์งธ๊น ํ์ด๋จธ ๊ตฌํํ๊ธฐ (0) | 2024.05.03 |
kotlin-android-extensions ๋ฅผ ๊ฑท์ด๋ด์. ๊ฑท์ด๋ด์! (2) | 2024.03.22 |
Android API Level 33 ์ ๋ฐ์ดํธ ์ ์ฉ (1) | 2023.08.22 |
Kotlin์ Coroutine, ์ฝ๋ฃจํด #1 (0) | 2023.01.31 |