경험의 기록

2021.04.20 - [Android/AAC, MVVM] - [Android] 안드로이드 DataBinding 사용하기

 

[Android] 안드로이드 DataBinding 사용하기

※ DataBinding 이란? 데이터와 뷰를 연결하는 작업을 레이아웃에서 처리 할 수 있게 해주는 라이브러리 findViewById (R.id.sample_text).apply { text = viewModel.userName } 예를들어, textView에 뷰모델에서..

hanyeop.tistory.com

데이터바인딩, 뷰바인딩을 사용하려면

액티비티, 프래그먼트마다 바인딩 코드를 작성해야한다.

이것은 매우 직관적이긴 하나 새로운 액티비티, 프래그먼트 생성시마다 반복해야 하므로 효율적이지 못하다.

 

따라서 BaseActivity, BaseFragment 를 통해 보일러 플레이트 코드(반복되는 코드)를 정리하여 쉽게 사용해보자.

 

 


1️⃣ Activity

기존방식

class MainActivity : AppCompatActivity() {
    private lateinit var binding : ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = DataBindingUtil.setContentView(this,R.layout.activity_main)
        binding.lifecycleOwner = this
    }
}

Activity의 경우 바인딩 생성 작업과 생명주기를 관찰할 수 있도록 전달해주는 코드가 필요하다.

 

BaseActivity

abstract class BaseActivity<T : ViewDataBinding>(
    @LayoutRes val layoutResId: Int
) : AppCompatActivity(){
    protected lateinit var binding: T

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = DataBindingUtil.setContentView(this, layoutResId)
        binding.lifecycleOwner = this
        init()
    }

    protected abstract fun init()
}

AppCompatActivity를 상속받는 추상클래스 BaseActivity 를 정의해주고,

제네릭을 활용하여 타입을 일반화한 코드를 작성해준다.

 

class MainActivity : BaseActivity<ActivityMainBinding>(R.layout.activity_main) {

    override fun init() {

    }
}

이제 BaseActivity 를 상속받아 액티비티에 맞게 구체화해주면

반복되는 코드를 줄일 수 있다.

 

2️⃣ Fragment

기존방식

class MainFragment : Fragment() {

    private var _binding: FragmentMainBinding? = null
    private val binding get() = _binding!!

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = DataBindingUtil.inflate(inflater, R.layout.fragment_main, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding.lifecycleOwner = viewLifecycleOwner
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}

이제 프래그먼트의 경우를 살펴보면, fragment는 view보다 오래 지속되기 때문에

메모리 누수 방지를 위해 onDestroyView에서 생명주기를 관리해주어야 하므로 중복되는 코드가 더 많다.

 

또한, 프래그먼트는 onDestroy가 호출되지 않은 상태에서 onCreateView가 여러번 호출될 수도 있기 때문에 lifecycleOwnerviewLifecycleOwner로 설정해주어 생명주기를 관리해야한다. (수정)

 

BaseFragment

abstract class BaseFragment<T: ViewDataBinding>(
    @LayoutRes val layoutResId: Int
) : Fragment(){
    private var _binding: T? = null
    protected val binding get() = _binding!!

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = DataBindingUtil.inflate(inflater, layoutResId, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding.lifecycleOwner = viewLifecycleOwner
        init()
    }

    protected abstract fun init()

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}

액티비티와 동일하게 추상클래스 BaseFragment 를 정의해주고,

타입을 일반화해준다.

 

class MainFragment : BaseFragment<FragmentMainBinding>(R.layout.fragment_main) {

    override fun init() {

    }
}

BaseFragment 를 상속받아 구체화한다.

 

 

전체 코드는 이곳에서 확인할 수 있습니다.

https://github.com/HanYeop/AndroidStudio-Practice2/tree/master/BaseEx

 

GitHub - HanYeop/AndroidStudio-Practice2: (2021.05.20~) 안드로이드 학습 내용 저장소

(2021.05.20~) 안드로이드 학습 내용 저장소. Contribute to HanYeop/AndroidStudio-Practice2 development by creating an account on GitHub.

github.com

 

참고

https://gift123.tistory.com/57

반응형

공유하기

facebook twitter kakaoTalk kakaostory naver band
loading