Fragment LiveData / LifeCycleOwner

최대환·2023년 12월 11일
0

Fragment에서 LiveData를 사용하기

btn1을 누르면 fragment가 생성되고 fragment안에있는 btn1을 누르면 숫자가 올라가는 앱을 만들거다.
우선 mainActivity에서 fragment를 만들고, 레이아웃을 만든다.

MainActivity
class MainActivity : AppCompatActivity() {

    private lateinit var binding : ActivityMainBinding

    val manager = supportFragmentManager

    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view)

        binding.btn1.setOnClickListener {
            val transaction1 = manager.beginTransaction()
            val fragment1 = BlankFragment1()
            transaction1.replace(R.id.frameArea, fragment1)
            transaction1.addToBackStack(null)
            transaction1.commit()
        }
    }
}
activity_main.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"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <Button
            android:id="@+id/btn1"
            android:text="btn1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>


        <androidx.fragment.app.FragmentContainerView
            android:id="@+id/frameArea"
            android:name="com.choidaehwan.fragmentlivedatalifecycleowner.BlankFragment1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

데이터를 관리해줄 ViewModel을 만들어준다.
뷰모델에서는 라이브데이터를 사용하게끔 만들어준다.

BlankViewModel1
class BlankViewModel1 : ViewModel() {

    private var _mutableCount = MutableLiveData(0)
    val liveCount : LiveData<Int>
        get() = _mutableCount

    fun plusCountValue(){
        _mutableCount.value = _mutableCount.value!!.plus(1)
    }
}

그리고 프래그먼트를 뷰결합과 뷰모델에 연동시킨다. 다만 여기서 observe를 통해 데이터의 변화를 관찰할때 파라미터에 this 대신에 viewLifecycleOwner를 써준다.
fragment에서 this는 LifecycleOwner역할을 수행하는데 이는 fragment의 생명주기를 따라가기때문에 fragment view의 생명주기를 따르는 viewLifecycleOwner를 사용해야한다.

BlankFragment1
class BlankFragment1 : Fragment() {

    private val TAG = "BlankFragment1"

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

    private lateinit var viewModel: BlankViewModel1

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

    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = FragmentBlank1Binding.inflate(inflater, container, false)
        val view = binding.root

        viewModel = ViewModelProvider(this).get(BlankViewModel1::class.java)

        return view
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        binding.btn1.setOnClickListener {
            viewModel.plusCountValue()
        }

        // this 대신에 viewLifecycleOwner를 사용한다
        viewModel.liveCount.observe(viewLifecycleOwner, Observer {
            binding.text1.text = it.toString()
        })
    }


    override fun onDestroyView() {
        super.onDestroyView()
        Log.d(TAG, "onDestroyView")
    }


    override fun onDestroy() {
        super.onDestroy()
        Log.d(TAG, "onDestroy")
    }
}
fragment_blank1.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".BlankFragment1">

    <!-- TODO: Update blank fragment layout -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:textSize="60sp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Frag1" />

        <TextView
            android:id="@+id/text1"
            android:text="0"
            android:textSize="60sp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

        <Button
            android:id="@+id/btn1"
            android:text="btn1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>


    </LinearLayout>



</FrameLayout>

이렇게하면 fragment에서 LiveData를 사용할 수 있다.

profile
나의 개발지식 output 공간

0개의 댓글