728x90

안드로이드 Fragment 예제를 간략하게 정리했다.

API Level 11(Android 3.0) 이상에서 지원한다. 요즈음에는 최소 4.4 이상으로 컴파일을 하므로 기본적으로 제공된다고 볼 수 있다.


Fragment를 사용하는 가장 큰 목적은 분할된 화면들을 독립적으로 구성하고 그 상태를 관리하는데 있다.

Fragment는 항상 Activity 위에 올라가 있어야 한다.

Activity 로 만들어진 화면을 분할하여 각각의 부분화면을 Fragment로 만들고 그 Fragment를 독립적으로 관리하는 것을 목표로 한다.


Fragment는 항상 Activity 내에 포함되어 있어야 하며 해당 Fragment의 수명 주기는 호스트 Activity의 수명 주기에 직접적으로 영향을 받는다.
예를 들어 Activity가 일시정지되는 경우, 그 안의 모든 Fragment도 일시정지되며 Activity가 소멸되면 모든 Fragment도 마찬가지로 소멸된다. 그러나 Activity가 실행 중인 동안에는 각 Fragment를 추가 또는 제거하는 등 개별적으로 조작할 수 있다.


Activity 의 UI를 보여주기 위해서 onCreate 메소드를 Override 하고 Layout Resource ID인 R.layout.activity_main을 파라미터로 넘기면서 setContentView 메소드를 호출한다.


먼저, MainActivity 에 표시될 Layout XML 구조는 아래에 버튼을 클릭하면 Fragment 화면이 변경되도록 구성했다.


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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">

    <LinearLayout
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:layout_above="@+id/tabmenuLayout" />

    <LinearLayout
        android:id="@+id/tabmenuLayout"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:orientation="horizontal"
        android:layout_alignParentBottom="true" >

        <Button
            android:id="@+id/btn_tab1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Tab 1"/>

        <Button
            android:id="@+id/btn_tab2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Tab 2"/>

        <Button
            android:id="@+id/btn_tab3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Tab 3"/>

    </LinearLayout>
</RelativeLayout>


fragment_container 에 표시될 Fragment XML 은 다음과 같다.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    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">

    <TextView
        android:gravity="center"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="프래그먼트 1" />

</RelativeLayout>

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    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:background="#ffe4e1">

    <TextView
        android:gravity="center"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="프래그먼트 2" />

</RelativeLayout>

<?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"
    android:orientation="vertical"
    android:background="#81DAF5" >

    <TextView
        android:id="@+id/fr_tv03"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:layout_centerInParent="true"
        android:text="프래그먼트 3"
        android:textStyle="bold"/>

</RelativeLayout>


Fragment01.java

Alt + Insert 키를 눌러서 아래 메소드를 추가한 다음에 view를 return해 주도록 코드를 수정한다.

Fragment는 Fragment Class 를 상속하여 만들 수 있다.

 public class Fragment01 extends Fragment {

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        // onCreateView() : 프래그먼트와 연관된 뷰 계층을 생성하기 위해 호출됨
        // Inflate the layout for this fragment
        ViewGroup rootView = (ViewGroup)inflater.inflate(R.layout.fragment_01, container, false);
        return rootView;
        //return super.onCreateView(inflater, container, savedInstanceState); // Alt + Insert키 누르면 자동 생성되는 return
    }
}


Fragment02.java

- Activity 에서 전달한 데이터를 받아서 화면에 표시하기

- Fragment 로 데이터 전달법은 구글에서 Passing data to activity and fragment in Android 로 검색하면 된다.

- onCreateView 에서 Activity 에서 전달한 데이터를 받아도 된다.

public class Fragment02 extends Fragment {
    TextView textView;
    String strtext;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            strtext = getArguments().getString("edttext"); // Activity 에서 받은 데이터
        }
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        ViewGroup rootView = (ViewGroup)inflater.inflate(R.layout.fragment_02, container, false);
        textView = (TextView) rootView.findViewById(R.id.fr_tv02);
        textView.setText(strtext);
        return rootView;
        //return super.onCreateView(inflater, container, savedInstanceState);
    }
}


Fragment03.java

 public class Fragment03 extends Fragment {
    TextView textView;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        // onCreateView()로 전달된 container 매개변수가 상위 ViewGroup 이며(액티비티의 레이아웃으로부터), 이 안에 프래그먼트 레이아웃이 삽입
        // savedInstanceState 매개변수는 Bundle이며, 프래그먼트가 재개되는 중에 프래그먼트의 이전 인스턴스에 대한 데이터를 제공
        // Inflate the layout for this fragment
        // Inflate 시키고자 하는 Layout 의 Resource ID, Inflated 된 Layout 의 상위가 될 ViewGroup
        ViewGroup rootView = (ViewGroup)inflater.inflate(R.layout.fragment_03, container, false);
        textView = (TextView) rootView.findViewById(R.id.fr_tv03);
        textView.setText("Fragment 3을 선택했네요.");
        return rootView;
    }
}


MainActivity.java

Activity에서 Fragment를 불러오는 기능을 수행

 public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    Context context;
    private Button tab1, tab2, tab3;
    private Fragment fragment = null;

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

        tab1 = findViewById(R.id.btn_tab1);
        tab2 = findViewById(R.id.btn_tab2);
        tab3 = findViewById(R.id.btn_tab3);

        tab1.setOnClickListener(this);
        tab2.setOnClickListener(this);
        tab3.setOnClickListener(this);

        if(findViewById(R.id.fragment_container) != null){
            if(savedInstanceState != null) return;
            Fragment01 fragment01 = new Fragment01();
            fragment01.setArguments(getIntent().getExtras());

            FragmentManager fragmentManager = getFragmentManager();
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
            // add() 메서드를 사용하여 프래그먼트를 추가하고, 추가할 프래그먼트와 이를 삽입할 뷰를 지정
            fragmentTransaction.add(R.id.fragment_container, fragment01);
            // FragmentTransaction을 변경하고 나면, 반드시 commit()을 호출해야 변경 내용이 적용됨
            fragmentTransaction.commit();
        }
        // 상세 설명은 https://developer.android.com/guide/components/fragments?hl=ko 참조
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn_tab1:
                fragment = new Fragment01();
                changeFragment(fragment);
                break;
            case R.id.btn_tab2:
                Bundle bundle = new Bundle();
                bundle.putString("edttext", "From Activity");
                fragment = new Fragment02();
                fragment.setArguments(bundle); // Fragment 로 데이터 전달
                changeFragment(fragment);
                break;
            case R.id.btn_tab3:
                fragment = new Fragment03();
                changeFragment(fragment);
                break;
        }
    }

    private void changeFragment(Fragment fragment) {
        // 프로그래밍 방식으로 프래그먼트를 기존의 ViewGroup에 추가
        // 액티비티가 실행 중인 동안에는 언제든 액티비티 레이아웃에 프래그먼트를 추가 가능
        // 액티비티 내의 프래그먼트를 관리하려면 FragmentManager를 사용해야 함.
        FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.replace(R.id.fragment_container,fragment);
        //fragmentTransaction.addToBackStack(null); // back 버튼을 눌렀을 때 동작하는 옵션.
        fragmentTransaction.commit(); // 트랜잭션을 액티비티에 적용하려면 반드시 commit()을 호출해야 함.
    }
}


Fragment는 Activity가 아니기 때문에 context를 갖지 않는다.
Fragment 구현시 context를 이용해야 할 경우 getActivity()함수를 이용한다.
getActivity().getApplicationContext();
getActivity().finish();
getActivity().getSharedPreferences("pref", Activity.MODE_PRIVATE);
getActivity().getSystemService(Context.USB_SERVICE);
getActivity().getSystemService(getActivity().CLIPBOARD_SERVICE);


테스트 파일

src.zip


사양이 낮은 폰에서 테스트를 못해봤는데 만약 동작되지 않는다면, import 수정.

http://www.androhub.com/android-pass-data-from-activity-to-fragment/ 에 나오는 import 참조하면 될 듯....


참조하면 도움되는 게시글

http://family-gram.tistory.com/60


728x90

'안드로이드 > Layout' 카테고리의 다른 글

ScrollView  (0) 2019.12.20
Dynamic Layouts  (0) 2019.01.06
FloatingActionButton(FAB)  (0) 2018.08.15
LinearLayout weight  (0) 2018.03.01
Android ViewFlipper(뷰플리퍼)  (0) 2017.05.02
블로그 이미지

Link2Me

,