마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

데이터바인딩한 데이터가 뷰에 세팅이 안됩니다..

0 추천

제목 그대로 데이터바인딩한 데이터가 뷰에 세팅이 되지 않습니다.. 에러마저 안뜨니

왜 세팅이안되는지 답답하기만 하네요 뭘 놓친건지..

class WritingRoutineFragment : Fragment() {
    var title: String? = null
    private lateinit var binding: FragmentWritingRoutineBinding

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

        arguments?.apply {
            title = getStringArrayList("title")?.joinToString(" / ")
        }
    }

    override fun onCreateView(inflater: LayoutInflater,
                              container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {

        binding = DataBindingUtil.inflate(inflater, R.layout.fragment_writing_routine, container,false)
        val view = binding.root

        return view
    }
    companion object {
        @JvmStatic
        fun newInstance(data: ArrayList<String>) =
            WritingRoutineFragment().apply {
                arguments = Bundle().apply {
                    putStringArrayList("title", data)
                }
            }
    }
}

 

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <data>
        <variable
            name="data"
            type="com.example.writeweight.fragment.WritingRoutineFragment" />
    </data>
    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        tools:context=".fragment.WritingRoutineFragment">
        <com.google.android.material.appbar.AppBarLayout
            android:id="@+id/appbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/Theme.AppBarOverlay"
            app:elevation="0dp">
            <androidx.appcompat.widget.Toolbar
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
                <TextView
                    android:id="@+id/body_part_detail_title"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:text="@{data.title}"
                    android:textColor="@color/white"
                    android:textAppearance="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"
                    android:layout_centerHorizontal="true" />
            </androidx.appcompat.widget.Toolbar>
        </com.google.android.material.appbar.AppBarLayout>
    </androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>

 

codeslave (3,940 포인트) 님이 2021년 5월 27일 질문

1개의 답변

0 추천
binding.data에 값을 할당하는 코드가 안보이네요. onViewCreated 에서 해주시면 될 것 같은데요. 그리고 바인딩 초기화 하실 때 DataBindingUtil 보다는 FragmentWrtingRoutineBinding.inflate 를 직접 사용하시면 굳이 layout id 를 사용하지 않아도 되므로 더 정확한 코드가 됩니다.

그리고 layout의 data에 Fragment를 사용하는 건 흔치않은 코드인 것 같아요. ViewModel에 LiveData를 지정해서 LiveData를 바인딩 시키는게 일반적입니다. 뷰와 로직을 분리하시는게 좋아요.
spark (224,800 포인트) 님이 2021년 5월 27일 답변
감사합니다 어렵네요 몇가지 질문드리겠습니다

1. 레이아웃의 데이터에 프래그먼트를 사용하는건 흔치않은 코드라고 하셨는데,
데이터바인딩에 프래그먼트를 한다는게 흔치않다는 말씀인지 아니면 저처럼 뷰와 로직을 구분하지않고 직접 코드상에 다 넣은걸 말씀하시는건가요..?
전자라면 싱글액티비로 앱을 만드려고하는데, 프래그먼트에서 데이터바인딩을 사용하고 싶은경우는 어떻게 되는건가요?

2.라이브데이터라는게 액티비티에서 뷰모델을 관찰해서 데이터가 변화시
실시간으로 뷰를 업데이트하는 개념으로 알고있는데, 저는 단순히 받은 데이터를
세팅하는 경우라 데이터가 변하는 일이없습니다. 라이브데이터를 사용해줘야하나요?
1. Activity나 Fragment는 일종의 View라고 볼 수 있습니다. 그리고 님이 데이터바인딩에 사용하려고 하는 것은 뷰로직과 관련된 데이터입니다. 이런 뷰로직 관련 데이터는 보통은 MVVM 같은 경우는 ViewModel에 위치하는 게 일반적인 접근방법입니다. 데이터바인딩의 경우 XML파일의 View layer의 출력을 담당하기 때문에 이 경우 Activity는 이와 관련해서 어떤 코드도 가지지 않도록 하는게 좋습니다. 서로 하는 일이 다르기 때문이죠. Activity는 데이터바인딩에 대해서 알 필요가 없는 클래스입니다. 물론 바인딩을 초기화하는 부분은 안드로이드 데이터바인딩을 사용하기 위해서는 꼭 필요한 코드입니다만 그 외에는 액티비티에 위치시키지 않는 것이 좋습니다.

2. 꼭 라이브 데이터를 사용할 필요는 없습니다. 라이브데이터나 ObservableField를 사용하지 않으시면 수동으로 이걸 구현주셔야 데이터바인딩이 동작을 합니다. 따라서 LiveData를 사용하지 않으시면 데이터바인딩을 사용하는데 쓸데없는 코드를 작성해야 하는 번거로움이 생깁니다. 그리고 LiveData가 LifecycleAware컴포넌트라고 불리는데, 라이프사이클에 대한 기본적인 처리를 해주고 있기 때문입니다. 예를 들면 observer가 있을 경우 라이프사이클이 액티브한 상태가 되면 자동으로 observer들에게 가지고 있던 데이터를 통보해주는 것과 같은 동작을 자동으로 처리해 줍니다. 따라서 이런 부분을 고려하셔서 다 코딩할 것이 아니라면, 이미 개발되어 있는 것을 가져다 쓸만하다고 생각합니다.
mvvm 코드를 여럿봐도 이해가 가면서도 막상 적용하려니 너무 어렵네요..

어떻게 분리를해야할지 너무 어렵네요
MVVM은 디자인 패턴이기 때문에 기본적으로 디잔인 패턴에 대한 공부를 진행하시는 것이 좋습니다. 그렇지 않으면, 샘플을 가져오더라도 님의 걸로 소화해서 코드를 작성하기가 만만치 않을 겁니다. 저도 MVVM을 사용하기 전에 관련된 패턴을 공부했었고, SOLID나 Clean Architecture 같은 관련 서적도 같이 봤었습니다. 무료 유투브나 온라인 튜토리얼도 많아요.
어느정도 기본적인 패턴 공부를 하시고 나서 보시면 훨씬 더 이해하기 쉬우실 거예요. 그리고 안드로이드 개발자 문서에 나오는 ViewModel + LiveData, Lifecycle 이런 부분에 대해서 정독하시길 추천드려요. (이런 점에서 최근의 안드로이드는 IOS보다는 개발이 더 힘든 것 같아요.)
...