데이터 바인딩 BindingAdapter
데이터 바인딩을 실무에 적용하기 위해서는 BindingAdapter를 자유자재로 다룰 수 있어야 합니다.
ImageView, ListView, RecyclerView등 기능이 복잡한 View는 BindingAdapter를 통해 데이터를 처리해주어야 하기 때문입니다.
1. 서버로부터 이미지를 받아야 되기 때문에 인터넷 접근 권한을 설정해줍니다.(Glide라이브러리)
<uses-permission android:name="android.permission.INTERNET" />
2.APP단계의 build.gradle에 Glide를 추가해줍니다.
//glide
implementation "com.github.bumptech.glide:glide:$glideVersion"
3.User.kt에 profile데이터(이미지 주소)와 BindingAdapter를 추가해 줍니다.
class User(val firstName: String, val lastName: String, val profile: String){
object MyBind{
@JvmStatic
@BindingAdapter("setImage")
fun setImageUrl(view: ImageView, profile: String){
Glide.with(view.context)
.load(profile)
.into(view)
}
}
}
BindingAdapter는 메모리 상에 올려서 사용해야 하기 때문에 자바에서는 static, 코틀린 에서는 object로 설정해서
사용해 줍니다.
(참고)아래는 자바 코드일 때의 User.class에 관한 코드입니다.
public class User{
public String firstName;
public String lastName;
public String profile;
@BindingAdapter("setImage")
public static void setImageUrl(ImageView view, String profile){
Glide.with(view.getContext())
.load(profile)
.into(view)
}
}
4. activity_main.xml에 ImageView를 추가합니다.
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<!-- data 이름을 user로 설정하였습니다. -->
<!-- type 은 User 클래스 위치와 함께 표시되어야 합니다. -->
<variable name="user" type="com.package.User" />
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
setImage="@{user.profile}" />
</LinearLayout>
</layout>
ImageView는 BindingAdapter에서 정한 setImage를 추가해 주고 user객체에서 profile(이미지 주소)를 가져옵니다.
5.User 객체에 profile 데이터를 추가해 줍니다.
class MainActivity: AppCompatActivity(){
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?){
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.acvitity_main)
binding.user = User("Black", "Jin", "https://이미지경로")
}
}
object MainBindingAdapter {
/**
* Main - 하단 탭 구성
*/
@JvmStatic
@BindingAdapter("mainActivity", "mainViewPager", "childFragmentManager", "lifecycle")
fun mainBottomTabLayoutAdapter(tabLayout: TabLayout, activity: MainActivity, viewPager2: ViewPager2, childFragmentManager: FragmentManager, lifecycle: Lifecycle){
viewPager2.apply {
adapter = MainViewPagerAdapter(childFragmentManager, lifecycle)
}
TabLayoutMediator(tabLayout, viewPager2){tab, position->
activity?.layoutInflater?.inflate(R.layout.custom_main_tab_item, null)?.apply{
findViewById<TextView>(R.id.tvMainTab).text = when(position){
MainTabItems.AREA.ordinal ->{
R.string.main_tab_item2.toResString()
}
MainTabItems.AROUNDME.ordinal ->{
R.string.main_tab_item3.toResString()
}
else ->{
R.string.main_tab_item1.toResString()
}
}
findViewById<ImageView>(R.id.ivMainTab).background = when(position){
MainTabItems.AREA.ordinal ->{
R.mipmap.ic_launcher.toDrawable()
}
MainTabItems.AROUNDME.ordinal ->{
R.mipmap.ic_launcher.toDrawable()
}
else ->{
R.mipmap.ic_launcher.toDrawable()
}
}
tab.customView = this
}
}.attach()
}
}
xml ==========
<data>
<variable
name="viewModel"
type="com.smadian.ainanny.vm.MainViewModel" />
<variable
name="activity"
type="com.smadian.ainanny.ui.main.MainActivity" />
<variable
name="childFragmentManager"
type="androidx.fragment.app.FragmentManager" />
<variable
name="lifecycle"
type="androidx.lifecycle.Lifecycle" />
</data>
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:layout_width="0dp"
android:layout_height="55dp"
android:background="@color/white"
android:fillViewport="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:mainActivity="@{activity}"
app:mainViewPager="@{viewPager}"
app:childFragmentManager="@{childFragmentManager}"
app:lifecycle="@{lifecycle}"
app:tabGravity="fill"
app:tabIndicatorHeight="0dp"
app:tabMode="fixed"
app:tabPaddingBottom="0dp"
app:tabPaddingEnd="0dp"
app:tabPaddingStart="0dp"
app:tabPaddingTop="0dp" />
Source ===============
binding.also {
it.viewModel = mainVM
it.activity = (activity as MainActivity)
it.childFragmentManager = childFragmentManager
it.lifecycle = lifecycle
참조 :
https://black-jin0427.tistory.com/91?category=727620
https://dev-imaec.tistory.com/41
'안드로이드' 카테고리의 다른 글
[Android] Dagger에 대해 알아보자 (0) | 2022.10.27 |
---|---|
[Android] Context에 대해 알아보자 (0) | 2022.10.27 |
[Android] Android Apk 패키징 v1, v2 (0) | 2022.10.27 |
[Android] Anko alert, startActivity에 대해 알아보자 (0) | 2022.10.27 |
[Android] Android DB Room에 대해 알아보자 (0) | 2022.10.25 |