Computer >> 컴퓨터 >  >> 프로그래밍 >> Android

안드로이드에서 프래그먼트(Fragment) 간 데이터 전달하는 방법 완벽 가이드

개요

이 튜토리얼에서는 안드로이드 앱에서 두 개의 프래그먼트(Fragment) 사이에 값을 전달하는 방법을 단계별로 알아봅니다. 첫 번째 프래그먼트의 EditText에 입력한 텍스트를 버튼 클릭 한 번으로 두 번째 프래그먼트의 TextView에 실시간으로 표시하는 예제를 구현해 보겠습니다.

프래그먼트 간 통신은 인터페이스(Interface) 패턴을 활용하는 것이 공식적으로 권장되는 방식입니다. 각 프래그먼트가 서로를 직접 참조하지 않고, 호스트 액티비티를 통해 이벤트를 전달함으로써 결합도를 낮추고 재사용성을 높일 수 있습니다.

Step 1 — 새 프로젝트 생성

Android Studio에서 File → New Project를 선택하고, 필요한 모든 세부 정보를 입력하여 새 프로젝트를 생성합니다.

Step 2 — 메인 레이아웃 작성 (activity_main.xml)

res/layout/activity_main.xml 파일에 아래 코드를 추가합니다. 두 개의 프래그먼트를 상하로 배치하는 구조입니다.

<RelativeLayout
   xmlns:android="https://schemas.android.com/apk/res/android"
   xmlns:tools="https://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:background="#574706"
   tools:context=".MainActivity">
   <fragment
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:name="app.com.sample.FragmentOne"
      android:id="@+id/fragment"
      android:layout_alignParentTop="true"
      android:layout_centerHorizontal="true"
      tools:layout="@layout/fragment_fragment_one" />
   <fragment
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:name="app.com.sample.FragmentTwo"
      android:id="@+id/fragment2"
      android:layout_below="@+id/fragment"
      android:layout_centerHorizontal="true"
      android:layout_marginTop="41dp"
      tools:layout="@layout/fragment_fragment_two" />
</RelativeLayout>

Step 3 — 메인 액티비티 구현 (MainActivity.java)

src/MainActivity.java에 다음 코드를 추가합니다. 핵심은 FragmentOne.OnFragmentInteractionListener 인터페이스를 구현(implements)한다는 점입니다. FragmentOne에서 전달된 값을 받아 FragmentTwo의 updateTextField() 메서드를 호출합니다.

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends AppCompatActivity implements FragmentOne.OnFragmentInteractionListener{
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
   }
   @Override
   public boolean onCreateOptionsMenu(Menu menu) {
      getMenuInflater().inflate(R.menu.menu_main, menu);
      return true;
   }
   @Override
   public boolean onOptionsItemSelected(MenuItem item) {
      int id = item.getItemId();
      if (id == R.id.textUpdate) {
         return true;
      }
      return super.onOptionsItemSelected(item);
   }
   @Override
   public void onFragmentInteraction(String userContent) {
      FragmentTwo fragmentTwo =
         (FragmentTwo)
         getSupportFragmentManager().findFragmentById(R.id.fragment2);
      fragmentTwo.updateTextField(userContent);
   }
}

Step 4 — 두 개의 프래그먼트 생성

FragmentOne과 FragmentTwo 두 개의 프래그먼트를 생성하고 아래 코드를 작성합니다.

a) FragmentOne.java — 값 전송 측

EditText에 입력된 값을 검증한 후, 리스너를 통해 액티비티로 전달하는 역할을 합니다. onAttach()에서 리스너를 초기화하며, 입력값이 비어 있으면 Toast로 경고를 표시합니다.

import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class FragmentOne extends Fragment {
   private OnFragmentInteractionListener mListener;
   private EditText userInput;
   private String userData;
   public FragmentOne() {
   }
   @Override
   public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
      View view = inflater.inflate(R.layout.fragment_fragment_one, container, false);
      userInput = view.findViewById(R.id.userInput);
      Button update = view.findViewById(R.id.button);
      update.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
            if(userInput.getText().toString().equals("")){
               Toast.makeText(getActivity(), "User input value must be filled",
               Toast.LENGTH_LONG).show();
               return;
            }
            userData = userInput.getText().toString();
            onButtonPressed(userData);
         }
      });
      return view;
   }
   public void onButtonPressed(String userContent) {
      if (mListener != null) {
         mListener.onFragmentInteraction(userContent);
      }
   }
   @Override
   public void onAttach(Activity activity) {
      super.onAttach(activity);
      try {
         mListener = (OnFragmentInteractionListener) activity;
      } catch (ClassCastException e) {
         throw new ClassCastException(activity.toString() + " must implement
         OnFragmentInteractionListener");
      }
   }
   @Override
   public void onDetach() {
      super.onDetach();
      mListener = null;
   }
   public interface OnFragmentInteractionListener {
      void onFragmentInteraction(String userContent);
   }
}

fragment_fragment_one.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
   xmlns:android="https://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:padding="4dp"
   android:paddingBottom="32dp">
   <EditText
      android:id="@+id/userInput"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:layout_alignParentTop="true"
      android:layout_centerHorizontal="true"
      android:layout_marginTop="16dp"
      android:ems="10"
      android:inputType="text">
      <requestFocus />
   </EditText>
   <Button
      android:id="@+id/button"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_centerHorizontal="true"
      android:layout_below="@id/userInput"
      android:layout_marginTop="20dp"
      android:padding="16dp"
      android:elevation="4dp"
      android:text="Update" />
</RelativeLayout>

b) FragmentTwo.java — 값 수신 측

전달받은 문자열을 TextView에 표시하는 updateTextField() 메서드를 제공합니다.

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class FragmentTwo extends Fragment {
   private TextView updateText;
   public FragmentTwo() {
   }
   @Override
   public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
      View view =
      inflater.inflate(R.layout.fragment_fragment_two, container, false);
      updateText = view.findViewById(R.id.textUpdate);
      return view;
   }
   public void updateTextField(String newText){
      updateText.setText(newText);
   }
}

fragment_fragment_two.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
   xmlns:android="https://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="match_parent">
   <TextView
      android:id="@+id/textUpdate"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text=""
      android:textSize="24sp"
      android:layout_alignParentTop="true"
      android:layout_centerHorizontal="true"
      android:textStyle="bold"
      android:layout_marginTop="32dp" />
</RelativeLayout>

Step 5 — 매니페스트 설정 (AndroidManifest.xml)

AndroidManifest.xml에 아래 코드를 추가합니다.

<?xml version="1.0" encoding="utf-8"?>
<manifest
   xmlns:android="https://schemas.android.com/apk/res/android"
   package="app.com.sample">
   <application
      android:allowBackup="true"
      android:icon="@mipmap/ic_launcher"
      android:label="@string/app_name"
      android:roundIcon="@mipmap/ic_launcher_round"
      android:supportsRtl="true"
      android:theme="@style/AppTheme">
      <activity android:name=".MainActivity">
         <intent-filter>
            <action
               android:name="android.intent.action.MAIN" />
            <category
               android:name="android.intent.category.LAUNCHER" />
         </intent-filter>
      </activity>
   </application>
</manifest>

앱 실행 및 결과 확인

이제 애플리케이션을 실행해 보겠습니다. 실제 안드로이드 기기가 컴퓨터와 연결되어 있다고 가정합니다. Android Studio에서 프로젝트의 액티비티 파일 중 하나를 연 뒤, 툴바의 Run(실행) 아이콘을 클릭하세요. 실행 옵션 목록에서 본인의 모바일 기기를 선택하면, 기기 화면에 아래와 같은 기본 화면이 표시됩니다.

안드로이드에서 프래그먼트(Fragment) 간 데이터 전달하는 방법 완벽 가이드

안드로이드에서 프래그먼트(Fragment) 간 데이터 전달하는 방법 완벽 가이드

마무리 정리

프래그먼트 간 데이터 전달의 핵심 흐름은 다음과 같습니다.

① FragmentOne → 버튼 클릭 시 입력값을 리스너로 전달
② MainActivity → 인터페이스 구현을 통해 값을 수신
③ FragmentTwo → findFragmentById()로 찾아 updateTextField() 호출

이처럼 인터페이스 기반 통신 패턴을 사용하면 프래그먼트가 특정 액티비티에 종속되지 않으면서도 안전하게 데이터를 주고받을 수 있습니다. 참고로 최신 안드로이드 개발 환경(AndroidX, Jetpack)에서는 ViewModel 공유나 Fragment Result API를 활용하는 방법도 널리 사용되고 있으니, 프로젝트 요구 사항에 맞게 선택하시기 바랍니다.