스팀 앱 개발기 #6 - 태그별 검색 내용을 보여줄 TagsFragment에 데이터 바인딩 적용

in kr-dev 커뮤니티2 years ago (edited)

안드로이드 스튜디오에서 tabbed activity를 생성하면, 탭들을 클릭하면 나타날 서브 화면들이 있죠. 이들은 프래그먼트(fragment)로 구현이 되고요. 이전 포스트에서는 HomeFragment, DashboardFragment, NotificationsFragment 클래스들의 이름들을 TagsFragment, ProfileFragment, WalletFragment로 변경하였습니다. 이들은 기본적으로 뷰 바인딩(view binding)이 적용되어 있는데요. 이번 포스트에서는 TagsFragment에 뷰 바인딩 대신 데이터 바인딩(data binding)을 적용할 예정입니다.


TagsFragment에 데이터 바인딩 적용 과정

TagsFragment는 태그별 포스트들을 보여줄 서브 화면을 담당하구요. 이것에 데이터 바인딩을 적용하는 과정을 보여드립니다. 개요는 다음과 같습니다.

  • 모듈의 build.gradle 파일에 데이터 바인딩 설정
  • 프래그먼트들의 레이아웃 XML 파일 변경
  • 프래그먼트 클래스 변경

모듈의 build.gradle 파일에 데이터 바인딩 설정

android 블록의 buildFeatues 블록 안에 아래와 같이 dataBinding를 true로 설정하는 문장을 추가해 줍니다. viewBinding을 true로 설정하는 문장은 뷰 바인딩을 데이터 바인딩으로 완전 대체 후 삭제할 예정입니다.

android {
    // ...
    buildFeatures {
        dataBinding true
        viewBinding true
    }
}

프래그먼트들의 레이아웃 XML 파일 변경

TagsFragment 클래스의 fragment_tags.xml 파일에 데이터 바인딩을 적용하겠습니다.

fragment_tags.xml 파일 변경 전
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/text_home"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:textAlignment="center"
        android:textSize="20sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
fragment_tags.xml 파일 변경

작업 과정은 다음과 같습니다.

  • XML 파일에 layout 요소 생성
  • 기존 최상위 요소의 ConstraintLayout 요소의 xmlns:android, xmlns:app, xmlns:tools 속성들은 layout 요소로 이동
  • ConstraintLayout 요소를 layout 요소 안으로 이동
  • layout 요소 안에 data 요소 추가
  • data 요소 안에 TagsViewModel 객체를 변수로 추가
  • TagsViewModel 변수의 text 필드와 text_tags 텍스트뷰의 text 속성을 바인딩

위 과정을 적용한 결과는 다음과 같습니다.

<?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="lee.dorian.steem_ui.ui.tags.TagsViewModel" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/text_tags"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="8dp"
            android:text="@{viewModel.text}"
            android:textAlignment="center"
            android:textSize="20sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</layout>

프래그먼트 클래스 변경

TagsFragment 클래스에 데이터 바인딩을 적용하겠습니다.

TagsFragment 클래스 변경 전
class TagsFragment : Fragment() {

    private var _binding: FragmentTagsBinding? = 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 {
        val homeViewModel =
            ViewModelProvider(this).get(TagsViewModel::class.java)

        _binding = FragmentTagsBinding.inflate(inflater, container, false)
        val root: View = binding.root

        val textView: TextView = binding.textTags
        homeViewModel.text.observe(viewLifecycleOwner) {
            textView.text = it
        }
        return root
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}
TagsFragment 클래스 변경

작업 과정은 다음과 같습니다.

  • 바인딩 객체 생성 코드 변경
    • 뷰 바인딩: 바인딩 클래스의 inflate 정적 메소드 활용
    • 데이터 바인딩: DataBindingUtil.inflate 메소드 활용
  • 뷰모델 관찰 코드 제거 (데이터 바인딩이 대신함)

위 과정을 적용한 결과는 다음과 같습니다.

class TagsFragment : Fragment() {

    private var _binding: FragmentTagsBinding? = 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 {
        val tagsViewModel =
            ViewModelProvider(this).get(TagsViewModel::class.java)

        _binding = DataBindingUtil.inflate(this.layoutInflater, R.layout.fragment_tags, null, false)
        binding.viewModel = tagsViewModel
        return binding.root
    }

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

GitHub Commit


지난 스팀 앱 개발기

Sort:  
 2 years ago 

[광고] STEEM 개발자 커뮤니티에 참여 하시면, 다양한 혜택을 받을 수 있습니다.

Upvoted! Thank you for supporting witness @jswit.
default.jpg

Coin Marketplace

STEEM 0.28
TRX 0.12
JST 0.032
BTC 61195.86
ETH 3009.46
USDT 1.00
SBD 3.80