Android Framgent 간 데이터 전달

timothy jeong·2021년 12월 2일
0

Android with Kotlin

목록 보기
55/69

네비게이션 컴포넌트의 추가 기능인 Safe Args 를 이용하는것이 좋다. Type Safe 하게 데이터를 전달할 수 있게 도와주기 때문에 의도치 않은 실수를 줄일 수 있다.

프로젝트 build.gradle 에 새로운 classpath 를 더해야한다. 이를 통해 Safe Args 플러그인을 이용하겠다는 것을 명시한다.

buildscript {
    repositories {
      ...
    }
    
    dependencies {
        classpath "com.android.tools.build:gradle:7.0.3"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0"
        classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.3.5"
    }
}

그리고 앱 모듈에 플러그인을 추가한다.

plugins {
    ...
    id 'androidx.navigation.safeargs'
}

네비게이션 컨트롤러에게 액션 아이디를 알려줘서 직접 프레그먼트를 옮겨다닐 수 있게 했던것 처럼, 컨트롤러에게 argument 를 전달함으로써 컨트롤러가 적절한 프레그먼트에 해당 argument 를 전달하게 한다.

이렇게 argument 를 전달할때 Directions 클래스가 사용된다. Safe-Args 플러그인을 호라성화 하면 안드로이드 스튜디오는 각각의 프레그먼트에 대해 Directions 을 생성한다.

Directions 클래스는 각각의 프레그먼트가 할당받은 네비게이션 액션에 대한 함수를 포함하고 있다. 이러한 함수들에 argument 로 우리가 보내고자하는 메시지를 전달하면 된다.

예시

TwoFragment 에서 ThreeFragment 로 메시지를 전달

fragment_two.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">

    <EditText
        android:id="@+id/editText"
        android:hint="please enter your email"
        android:inputType="textEmailAddress"
        android:autofillHints="emailAddress"
        android:layout_width="match_parent"
        android:layout_height="480dp"
        android:gravity="center"
        android:textSize="40sp" />

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

</LinearLayout>

fragment_three.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">

    <TextView
        android:id="@+id/myText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="@string/email_value"
        android:textSize="40sp" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Go First"/>

</LinearLayout>

네비게이션 그래프

이러한 프레그먼트에 대해 네비게이션 그래프를 등록한다. 여기서 해당 프레그먼트가 어떤 argumet 를 받을 것인지 명시한다.

<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/nav_graph"
    app:startDestination="@id/oneFragment">

    <fragment
        android:id="@+id/twoFragment"
        android:name="com.examle.test.TwoFragment"
        android:label="TwoFragment" >
        <action
            android:id="@+id/toThreeFragment"
            app:destination="@id/threeFragment" />
    </fragment>

    <fragment
        android:id="@+id/threeFragment"
        android:name="com.examle.test.ThreeFragment"
        android:label="ThreeFragment">
        <argument
            android:name="message_email"
            app:argType="string" />
    </fragment>
</navigation>

argument 보내기

그리고 프레그먼트 뷰를 구성할때 Directions 클래스를 이용한다.

class TwoFragment: Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_two, container, false)
        val button = view.findViewById<Button>(R.id.button)
        val editText = view.findViewById<EditText>(R.id.editText)

        button.setOnClickListener {
            val messageEmail = editText.text.toString()
            val action = TwoFragmentDirections.toThreeFragment(messageEmail)
            view.findNavController().navigate(action)
        }
        return view
    }
}

argment 받기

class ThreeFragment: Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_three, container, false)
        val message = ThreeFragmentArgs.fromBundle(requireArguments()).messageEmail
        val text = view.findViewById<TextView>(R.id.myText)
        text.text = message
profile
개발자

0개의 댓글