오늘이라도

[Android] 18. 프래그먼트(Fragment) 간 데이터 전달, 프래그먼트 전환 본문

취업성공패키지 SW 개발자 교육/Android

[Android] 18. 프래그먼트(Fragment) 간 데이터 전달, 프래그먼트 전환

upcake_ 2020. 5. 29. 09:42
반응형

https://github.com/upcake/Class_Examples

교육 중에 작성한 예제들은 깃허브에 올려두고 있습니다. 

gif 파일은 클릭해서 보는 것이 정확합니다.


 - 프래그먼트(Fragment) 간 데이터 전달 입출력, 프래그먼트 전환 -

▲프래그먼트 간 데이터 전달, 프래그먼트 전환 작동 화면

 

▼activity_main.xml

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

    <!--전체적인 레이아웃을 잡음-->
    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <!--액션바 레이아웃-->
        <com.google.android.material.appbar.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="clip_horizontal|center"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@color/design_default_color_primary_dark"
                android:elevation="1dp"
                android:theme="@style/ThemeOverlay.AppCompat.Dark">
                <!--elevation : 약간 떠있는 느낌-->

                <TextView
                    android:id="@+id/titleText"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="타이틀"
                    android:textAppearance="@style/Widget.AppCompat.Toolbar"
                    android:textColor="#FFFFFF"
                    android:textSize="24sp" />
            </androidx.appcompat.widget.Toolbar>

            <!--탭 레이아웃-->
            <!--tabMode : fixed면 탭이 고정된 길이를 갖게끔 자동으로 나눠진다-->
            <!--scrollable이면 옆으로 넘길 수 있게 된다-->
            <com.google.android.material.tabs.TabLayout
                android:id="@+id/tabs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@android:color/background_light"
                android:elevation="1dp"
                app:tabGravity="fill"
                app:tabMode="fixed"
                app:tabSelectedTextColor="@color/colorAccent"
                app:tabTextColor="@color/colorPrimaryDark" />
        </com.google.android.material.appbar.AppBarLayout>

        <FrameLayout
            android:id="@+id/contatiner"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">

        </FrameLayout>
    </androidx.coordinatorlayout.widget.CoordinatorLayout>
</RelativeLayout>

 

▼MainActivity.java

package com.example.my24_tab1;

import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;

import android.os.Bundle;
import android.util.Log;

import com.google.android.material.tabs.TabLayout;

public class MainActivity extends AppCompatActivity {
    //로그캣 사용 준비
    private static final String TAG = "MainActivity";

    //객체 선언
    Toolbar toolbar;
    TabLayout tabs;
    Fragment1 fragment1;
    Fragment2 fragment2;
    Fragment3 fragment3;

    Fragment selected = null;

    Bundle mBundle; //main bundle

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //툴바 설정
        toolbar = findViewById(R.id.toolbar);
//      setSupportActionBar(toolbar);

        //액션바 설정
        ActionBar actionBar = getSupportActionBar();
        actionBar.setDisplayShowTitleEnabled(false);
        actionBar.hide();

        //프래그먼트 초기화
        fragment1 = new Fragment1();
        fragment2 = new Fragment2();
        fragment3 = new Fragment3();

        //프래그먼트 넣기(바꾸기)
        getSupportFragmentManager().beginTransaction().replace(R.id.contatiner, fragment1).commit();

        //탭 만들기 (동적)
        tabs = findViewById(R.id.tabs);
        tabs.addTab(tabs.newTab().setText("통화 기록"));
        tabs.addTab(tabs.newTab().setText("스팸 기록"));
        tabs.addTab(tabs.newTab().setText("연락처"));

        //탭이 선택되었을때 작동하는 메서드
        tabs.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                int position = tab.getPosition();
                Log.d(TAG, "선택된 탭 : " + position);

                if (position == 0) {
                    selected = fragment1;
                } else if (position == 1) {
                    selected = fragment2;
                } else if (position == 2) {
                    selected = fragment3;
                }

                //선택된 프래그먼트로 바꾸기
                getSupportFragmentManager().beginTransaction().replace(R.id.contatiner, selected).commit();
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });
    }//onCreate()

    public void fragBtnClick(Bundle bundle) {
        this.mBundle = bundle;
    } //fragBtnClcick()

} //MainActivity

 

▼fragment1.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#00BCD4">

    <Button
        android:id="@+id/button2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="첫 번째"/>

    <TextView
        android:id="@+id/textView1"
        android:layout_width="match_parent"
        android:layout_height="312dp"
        android:textColor="#FFFFFF"
        android:textSize="24sp" />
</LinearLayout>

▼Fragment1.java

package com.example.my24_tab1;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import com.google.android.material.tabs.TabLayout;

public class Fragment1 extends Fragment {
    //객체 선언
    Button button2;
    TextView textView1;

    MainActivity activity;
    String sendData, receiveData;
    StudentDTO student1;

    Context context;

    //onAttach : 프래그먼트와 액티비티가 연결될때 호출되는 메서드
    //onDetach : 프래그먼트와 액티비티의 연결이 끊길때 호출되는 메서드
    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        this.context = context;

        //메시지 송수신에 필요한 객체 초기화
        activity = (MainActivity) getActivity();
        sendData = "프래그먼트1에서 보낸 데이터입니다.";
        receiveData = "";
        student1 = new StudentDTO("KIM", 25);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        //XML, java 연결
        //XML이 메인에 직접 붙으면 true, 프래그먼트에 붙으면 false
        ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment1, container, false);

        //객체 초기화
        textView1 = rootView.findViewById(R.id.textView1);
        button2 = rootView.findViewById(R.id.button2);

        //텍스트뷰1에 프래그먼트 3에서 보낸 데이터 받기
        if(activity.mBundle != null) {
            Bundle bundle = activity.mBundle;
            receiveData = bundle.getString("sendData");
            StudentDTO student3 = (StudentDTO) bundle.getSerializable("student3");
            String name = student3.getName();
            int age = student3.getAge();
            int index = bundle.getInt("index");

            textView1.append(receiveData + "\n");
            textView1.append("name : " + name + "\nage : " + age + "\nindex : " + index);
            activity.mBundle = null;
        }

        //버튼2에 기능 추가 : 프래그먼트 2로 데이터 보내기
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Bundle bundle = new Bundle();
                bundle.putString("sendData", sendData);
                //bundle.putSerializable() : 객체를 보낼때 사용함
                bundle.putSerializable("student1", student1);
                bundle.putInt("index", 0);

                activity.fragBtnClick(bundle);

                //두 번째 탭을 선택(첫 번째 탭은 index가 0)
                TabLayout.Tab tab = activity.tabs.getTabAt(1);
                tab.select();
            }
        });

        return rootView;
    }
}

 

▼fragment2.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#2196F3">

    <Button
        android:id="@+id/button3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="두 번째"/>

    <TextView
        android:id="@+id/textView2"
        android:layout_width="match_parent"
        android:layout_height="324dp"
        android:textColor="#FFFFFF"
        android:textSize="24sp" />
</LinearLayout>

 

▼Fragment2.java

package com.example.my24_tab1;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import com.google.android.material.tabs.TabLayout;

public class Fragment2 extends Fragment {
    //객체 선언
    Button button3;
    TextView textView2;

    MainActivity activity;
    String sendData, receiveData;
    StudentDTO student2;

    Context context;

    //onAttach : 프래그먼트와 액티비티가 연결될때 호출되는 메서드
    //onDetach : 프래그먼트와 액티비티의 연결이 끊길때 호출되는 메서드
    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        this.context = context;

        //메시지 송수신에 필요한 객체 초기화
        activity = (MainActivity) getActivity();
        sendData = "프래그먼트2에서 보낸 데이터입니다.";
        receiveData = "";
        student2 = new StudentDTO("LEE", 22);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        //XML, java 연결
        //XML이 메인에 직접 붙으면 true, 프래그먼트에 붙으면 false
        ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment2, container, false);

        //객체 초기화
        textView2 = rootView.findViewById(R.id.textView2);
        button3 = rootView.findViewById(R.id.button3);

        //텍스트뷰2에 프래그먼트 1에서 보낸 데이터 받기
        if(activity.mBundle != null) {
            Bundle bundle = activity.mBundle;
            receiveData = bundle.getString("sendData");
            StudentDTO student1 = (StudentDTO) bundle.getSerializable("student1");
            String name = student1.getName();
            int age = student1.getAge();
            int index = bundle.getInt("index");

            textView2.append(receiveData + "\n");
            textView2.append("name : " + name + "\nage : " + age + "\nindex : " + index);
            activity.mBundle = null;

        }

        //버튼 3에 기능 추가 : 프래그먼트 3으로 데이터 보내기
        button3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Bundle bundle = new Bundle();
                bundle.putString("sendData", sendData);
                //bundle.putSerializable() : 객체를 보낼때 사용함
                bundle.putSerializable("student2", student2);
                bundle.putInt("index", 1);

                activity.fragBtnClick(bundle);

                //세 번째 탭을 선택(두 번째 탭은 index가 1)
                TabLayout.Tab tab = activity.tabs.getTabAt(2);
                tab.select();
            }
        });

        return rootView;
    }
}

 

▼fragment3.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#673AB7">

    <Button
        android:id="@+id/button4"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="세 번째"/>

    <TextView
        android:id="@+id/textView3"
        android:layout_width="match_parent"
        android:layout_height="321dp"
        android:textColor="#FFFFFF"
        android:textSize="24sp" />
</LinearLayout>

▼Fragmnet3.java

package com.example.my24_tab1;

import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import com.google.android.material.tabs.TabLayout;

public class Fragment3 extends Fragment {
    //객체 선언
    Button button4;
    TextView textView3;

    MainActivity activity;
    String sendData, receiveData;
    StudentDTO student3;

    Context context;

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        this.context = context;

        //메시지 송수신에 필요한 객체 초기화
        activity = (MainActivity) getActivity();
        sendData = "프래그먼트3에서 보낸 데이터입니다.";
        receiveData = "";
        student3 = new StudentDTO("PARK", 31);

    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment3, container, false);

        //객체 초기화
        textView3 = rootView.findViewById(R.id.textView3);
        button4 = rootView.findViewById(R.id.button4);

        //텍스트뷰3에 프래그먼트 2에서 보낸 데이터 받기
        if(activity.mBundle != null) {
            Bundle bundle = activity.mBundle;
            receiveData = bundle.getString("sendData");
            StudentDTO student2 = (StudentDTO) bundle.getSerializable("student2");
            String name = student2.getName();
            int age = student2.getAge();
            int index = bundle.getInt("index");

            textView3.append(receiveData + "\n");
            textView3.append("name : " + name + "\nage : " + age + "\nindex : " + index);
            activity.mBundle = null;
        }

        //버튼 4에 기능 추가 : 프래그먼트 1로 데이터 보내기
        button4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Bundle bundle = new Bundle();
                bundle.putString("sendData", sendData);
                bundle.putSerializable("student3", student3);
                bundle.putInt("index", 2);

                activity.fragBtnClick(bundle);

                //첫 번째 탭을 선택
                TabLayout.Tab tab = activity.tabs.getTabAt(0);
                tab.select();
            }
        });

        return rootView;
    }
}
반응형