프로그래밍/안드로이드

안드로이드 - FragmentManager를 이용한 프래그먼트 추가, 삭제, 교체, 숨김

가카리 2015. 9. 12. 15:16
반응형

프래그먼트를 실행중에 편집하기 위해서는 프래그먼트 관리자를 사용해야한다.

 

    FragmentManager Activity.getFragmentManager()

    FragmentManager Fragment.getFragmentManager()

 

그리고 프래그먼트를 관리하려면 먼저 대상 프래그먼트를 검색해야 한다.

 

    Fragment findFragmentById(int id)

    Fragment findFragmentByTag(String tag)

 

프래그먼트는 다음 3가지 방식으로 지칭한다.

1. id: 프래그먼트를 배치할 때 지정한 android:id 속성의 정수값을 이용한다.

2. 부모의 id : 실행 중에 생성한 프래그먼트는 고유한 id가 없다. 그래서 부모의 id를 통해 프래그먼트를 찾는다. (단 첫 번째 차일드만 검색 가능)

3. 문자열 형태의 태그 : 실행 중에 프래그먼트를 생성할 때 고유한 이름의 태그를 붙일 수 있는데 이 태그로부터 프래그먼트를 검색한다.

 

프래그먼트를 편집하려면 다음 메소드로 트랜잭션을 시작한다.

 

    FragmentTransaction beginTransaction()

 

이 메소드의 리턴되는 FragmentTransaction 객체의 편집 메소드를 호출하여 프래그먼트를 편집한다.

 

프래그먼트를 추가할 때는 다음 메소드를 호출한다.

    

    FragmentTransaction add(int containerViewId, Fragment fragment [, String tag])

    FragmentTransaction add(Fragment fragment, String tag)

 

contatinerViewId는 프래그먼트가 추가될 부모 뷰의 id이고 이 값이 0이면 프래그먼트가 화면에 나타나지 않음.

fragment는 추가할 프래그먼트 객체, tag인수로 이름을 지정

 

프래그먼트를 제거할 때는 다음 메소드를 호출한다.

 

    FragmentTransaction remove(Fragment fragment)

 

이미 추가되어 있는 프래그먼트를 다른 프래그먼트로 대체할 때는 다음 메소드를 호출한다.

 

    FragmentTransaction replace(int containerViewId, Fragment fragment [, String tag])

 

컨테이너의 id와 새로 대체할 프래그먼트를 인수로 전달하며 차후의 작업을 위해 태그명을 지정할 수 있다.

 

프래그먼트를 숨기거나 보일 때는 다음 두 메소드를 호출한다.

 

    FragmentTransaction show(Fragment fragment)

    FragmentTransaction hide(Fragment fragment)

 

모든 편집이 완료된 후에 최종적으로 다음 메소드를 호출하여 편집을 실행한다.

 

    int commit()

 

이 메소드를 트랜잭션을 직접 처리하는 것이 아니라 스레드가 한가할 때 처리하도록 스케쥴링한다.

 

이번에 예제는 프래그먼트를 추가, 삭제, 교체, 숨김을 실습한다.

 

다음과 같이 총 5개의 파일을 만든다.

 

 

activity_fragment_manager_test.xml

<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"

>

 

<Button

android:id="@+id/btnadd"

android:layout_height="wrap_content"

android:layout_width="wrap_content"

android:onClick="mOnClick"

android:text="Add"

/>

<Button

android:id="@+id/btnremove"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:onClick="mOnClick"

android:text="Remove"

/>

<Button

android:id="@+id/btnreplace"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:onClick="mOnClick"

android:text="Replace"

/>

<Button

android:id="@+id/btnhideshow"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:onClick="mOnClick"

android:text="Hide"

/>

<FrameLayout

android:id="@+id/frame"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

/>

 

</LinearLayout>

 

 

counterfragment.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:gravity="center_horizontal"

android:background="#ffff00"

>

 

<TextView

android:id="@+id/txtcounter"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:textColor="#ff0000"

android:textSize="40sp"

android:text="0"

/>

<Button

android:id="@+id/btnincrease"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Increase"

/>

 

</LinearLayout>

    

 

textfragment.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

android:background="#00ff00"

>

 

<TextView

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="문자열 입력 프래그먼트"

/>

<EditText

android:id="@+id/text"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:background="#ff0000"

android:text="String"

/>

 

</LinearLayout>

 

 

CouterFragment.java

package com.example.ch20_fragmentmanager;

 

import android.app.Fragment;

import android.os.Bundle;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.Button;

import android.widget.TextView;

 

 

public class CounterFragment extends Fragment{

    

    @Override

    public View onCreateView(LayoutInflater inflater, ViewGroup container,

            Bundle savedInstanceState) {

        // TODO Auto-generated method stub

        //onCreateView 프래그먼트의 UI 처음 그릴때 호출한다.

        //그래서 여기서 XML 이용해서 프래그먼트 UI 구성해준다.

        //container 전개자를 사용하여 xml 가져온다

        View root = inflater.inflate(R.layout.counterfragment, container, false);

        

        Button btnIncrease = (Button)root.findViewById(R.id.btnincrease);

        final TextView textCounter = (TextView)root.findViewById(R.id.txtcounter);

      

        

        if(savedInstanceState != null){

            textCounter.setText(Integer.toString(savedInstanceState.getInt("counter")));

        }

          

        

        //간단한 버튼 클릭 리스너 달아줌

        btnIncrease.setOnClickListener(new Button.OnClickListener(){

 

            @Override

            public void onClick(View arg0) {

                // TODO Auto-generated method stub

                int count = Integer.parseInt(textCounter.getText().toString());

                textCounter.setText(Integer.toString(count + 1));

            }

            

        });

        

        return root;

    

    }

    

    //장비의 설정 상태 변경, 화면 방향 변경시에 다음 메소드가 호출된다.

    public void onSaveInstanceState(Bundle outState){

        super.onSaveInstanceState(outState);

        

        TextView textCounter = (TextView)getView().findViewById(R.id.txtcounter);

        int a = Integer.parseInt(textCounter.getText().toString());

        outState.putInt("counter", a);//번들에 저장 키와 값으로...

    }

 

}

 

 

FragmentManagerTest.java

package com.example.ch20_fragmentmanager;

 

import android.app.Activity;

import android.app.Fragment;

import android.app.FragmentManager;

import android.app.FragmentTransaction;

import android.os.Bundle;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.TextView;

import android.widget.Toast;

 

 

public class FragmentManagerTest extends Activity {

 

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_fragment_manager_test);

    }

 

    public void mOnClick(View v){

        //프래그먼트 관리자를 가져옴

        FragmentManager fm = getFragmentManager();

        //프래그먼트를 찾음

        Fragment fragment = fm.findFragmentById(R.id.frame);

        

        switch(v.getId()){

        case R.id.btnadd://프래그먼트 생성

            if(fragment == null){

                //프래그먼트가 없으면 다음 트랜잭션으로 생성한다.

                FragmentTransaction tr = fm.beginTransaction();

                CounterFragment cf = new CounterFragment();

                tr.add(R.id.frame, cf, "counter");

                tr.commit();

            }else{

                Toast.makeText(this, "이미 추가되어 있습니다.", 0).show();

            }

            break;

        case R.id.btnremove:

            if(fragment == null){

                Toast.makeText(this, "프래그먼트가 없습니다.", 0).show();

            }else{

                //프래그먼트가 있으면 다음 트랜잭션으로 제거한다.

                FragmentTransaction tr = fm.beginTransaction();

                tr.remove(fragment);

                tr.commit();

            }

            break;

        case R.id.btnreplace:

            if(fragment == null){

                Toast.makeText(this, "프래그먼트가 없습니다.", 0).show();

            }else{

                //프래그먼트가 있으면 다음 트랜잭션으로 교체한다.

                FragmentTransaction tr = fm.beginTransaction();

                if(fragment.getTag() == "counter"){//counter태그를 가진 프래그먼트면

                    TextFragment tf = new TextFragment();//이녀석으로 바꿈

                    tr.replace(R.id.frame, tf, "text");

                }else{//아니면 다른녀서긍로 바꿈

                    CounterFragment cf = new CounterFragment();

                    tr.replace(R.id.frame, cf, "counter");

                }

                tr.commit();

            }

            break;

        case R.id.btnhideshow:

            if(fragment == null){

                Toast.makeText(this, "프래그먼트가 없습니다.", 0).show();

            }else{//프래그먼트가 있다면

                FragmentTransaction tr = fm.beginTransaction();

                if(fragment.isHidden()){//여기서 숨겨졌으면 보이게 하고 보이고있으면 숨김으로 바꿈

                    tr.show(fragment);

                }else{

                    tr.hide(fragment);

                }

                tr.commit();

            }

            break;

        }

        

        

    }

    

    public static class TextFragment extends Fragment{

        public View onCreateView(LayoutInflater inflater, ViewGroup container,

                Bundle savedInstanceState){

            View root = inflater.inflate(R.layout.textfragment, container, false);

            TextView text = (TextView)root.findViewById(R.id.text);

            text.setSaveEnabled(true);

            return root;

        }

        

    }

}

 

 

 

 

실행 화면

첫 화면에서 Add를 누르면

_

아래와 같이 프래그먼트가 추가된다.

 

Remove를 누르면 생성된 프래그먼트가 다시 제거된다.

 

 

Replace를 누르면 프래그먼트가 교체된다.

 

Hide를 누르면 프래그먼트가 숨김이 된다.

 

다시 Hide를 누르면 생긴다.