[Android] 안드로이드 정리 (10) - 프래그먼트 (Fragment)
Android

[Android] 안드로이드 정리 (10) - 프래그먼트 (Fragment)

728x90

 

 

출처 : Do it! 안드로이드 앱 프로그래밍 / 정재곤

 

 

프래그먼트란?

 하나의 액티비티에서 화면의 아래쪽 일부분에 독립적인 레이아웃을 만들고 그 안에서 동영상을 재생하고 싶다면 어떻게 구성해야 할까? 또는 A 액티비티에서 사용하는 글쓰기 기능을 B 액티비티에서도 사용하고 싶을땐 어떻게 해야 할까?

 안드로이드 정리 (5) - 레이아웃 인플레이션 이해하기에서 부분 화면을 뷰그룹 객체로 객체화(인플레이션)한 후 메인 레이아웃에 추가하는 방법에 대해 설명했다. 하지만 이와 같은 방법은 단말의 리소스를 많이 사용하는 비효율적인 방법이다.

 하나의 화면을 여러 부분으로 나눠서 보여주거나 각각의 부분 화면 단위로 바꿔서 보여주고 싶을 때 사용하는 것이 프래그먼트(Fragment)이다. 프래그먼트는 코드가 복잡해지는 문제를 해결하기 위해 각 부분 화면의 코드를 분리시킨 것이다. 따라서 프래그먼트는 항상 액티비티 위에 올라가 있어야 한다.

 프래그먼트는 아래의 그림과 같은 형태로 동작한다. 프래그먼트매니저가 프래그먼트들을 독립적으로 동작할 수 있게끔 관리해준다.

출처 : Do it! 안드로이드 앱 프로그래밍

 또한 프래그먼트가 화면 전체를 채우도록 할 수 있어 원하는 시점에 다른 프래그먼트로 바꿔서 보여줄 수도 있다. 액티비티는 시스템에서 관리하지만 프래그먼트는 액티비티 위에 올라가 있어 액티비티를 전환하지 않고도 훨씬 가볍게 화면 전환 효과를 만들 수 있게 된다.

 

 

프래그먼트를 화면에 추가하는 방법

 프래그먼트는 액티비티를 본떠 만든 것이기 때문에 프래그먼트를 만들 때도 액티비티를 만들 때의 과정과 비슷하다. 즉, 프래그먼트도 하나의 XML 레이아웃과 하나의 자바 소스 파일로 동작하게 된다.

 하지만 프래그먼트에는 setContentView() 메소드가 없다. 따라서 인플레이션 객체인 LayoutInflater를 사용해 인플레이션을 진행해야 한다. 인플레이션은 onCreateView() 메소드 안에서 진행된다. onCreateView() 메소드는 콜백 메소드로 인플레이션이 필요한 시점에 자동으로 호출된다. 따라서 이 메소드 안에서 인플레이션을 위한 inflage() 메소드를 호출하면 되고 인플레이션 과정이 끝나면 프래그먼트가 하나의 뷰처럼 동작할 수 있게 된다.

 

 

> 프래그먼트 화면에 추가하는 예제

MainFragment

package com.example.project00_java;

import android.os.Bundle;

import androidx.fragment.app.Fragment;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;


public class MainFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_main, container, false);
    }
}

MainActivity

package com.example.project00_java;

import android.os.Bundle;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

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

fragment_main

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    tools:context=".MainFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello_blank_fragment" />

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

</LinearLayout>

activity_main

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <fragment
        android:id="@+id/fragment"
        android:name="com.example.project00_java.MainFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

 

> 버튼을 클릭했을 때 프래그먼트 추가하기 예제

MainActivity

package com.example.project00_java;

import android.os.Bundle;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    MainFragment mainFragment;
    MenuFragment menuFragment;

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

        mainFragment = (MainFragment) getSupportFragmentManager().findFragmentById(R.id.mainFragment);
        menuFragment = new MenuFragment();
    }

    public void onFragmentChanged(int index) {
        System.out.println(mainFragment);
        System.out.println(menuFragment);

        if (index == 0) {
            getSupportFragmentManager().beginTransaction().replace(R.id.container, menuFragment).commit();
        } else if (index == 1) {
            getSupportFragmentManager().beginTransaction().replace(R.id.container, mainFragment).commit();
        }
    }
}

MainFragment

package com.example.project00_java;

import android.os.Bundle;

import androidx.fragment.app.Fragment;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;


public class MainFragment extends Fragment {

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

        Button button = rootView.findViewById(R.id.button8);
        button.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
                MainActivity activity = (MainActivity) getActivity();
                activity.onFragmentChanged(0);
            }
        });
        return rootView;
    }
}

MenuFragment

package com.example.project00_java;

import android.os.Bundle;

import androidx.fragment.app.Fragment;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;


public class MenuFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_menu, container, false);
    }
}

activity_main

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

    <fragment
        android:id="@+id/mainFragment"
        android:name="com.example.project00_java.MainFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

fragment_main

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    tools:context=".MainFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello_blank_fragment" />

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

</LinearLayout>

fragment_menu

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#A53F3F"
    tools:context=".MenuFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello_blank_fragment" />

</LinearLayout>
728x90