본문 바로가기

아옳옳의 코딩공부/아옳옳의 안드로이드스튜디오

2021-04-01안드로이드 스튜디오(프래그먼트)

반응형

여러개의 화면을 구성할때 보통 각각의 액티비티를 만들어 사용하는 방식을 사용했었다. 

하지만 화면의 일부분에 독립적인 레이아웃을 만들고 그 안에서 작동하게 만들때 사용하게 된다

그리고 화면이 큰 테블릿에서 왼쪽에 메뉴화면 오른쪽에 메뉴의 상세 정보를 나타낼때 사용되고 ,

한 화면에 모든코드가 다 들어간다면 한 곳에 너무 많은 코드가 있기때문에 복잡해 지는것을 방지 하고자 

플래그먼트를 사용해 코드를 분할해 독립적으로 구성하고 관리하는대 있다 .

 

즉 플래그먼트의 사용목적은 

분할된 화면들을 독립적으로 구성하기 위해 사용함

분항된 화면들의 상태를 관리하기 위해 사용함 

그냥 액티비티로 했을경우 리소스를 더 많이 잡아 먹는다

 

 

 

위 그림을 보면 이해가 될것인데 . 보이는것처럼 메인액티비티 위에 각각의 프래그먼트를 사용하여 다른 화면들을 만들었다. 즉 액티비티위 위에 올라가는 화면의 일부 "부분 화면" 이라고 생각하면 된다 

 

프래그먼트를 처음 개발한 사람은 프래그먼트를 만들때 액티비티와 똑같은 형식으로 만들었다. 

액티비티는 액티비티 매니저가 관리를 하지만 프래그먼트는 프래그먼트 매니저가 관리를 해준다 

 

새로 만든 프래그먼트는 메인액티비티에 추가하는 방법은 XML 레이아웃에 추가하거나 또느 소스코드에서 new 연산자로 객체를 만든 후 프래그먼트 매니저로 추가할 수 있다. 

 

자그럼 XML파일에 추가하는 방법을 먼저 보겠다 

프래그먼트를 만들게 되면 엄청 복잡하고 많은 코드가 나오게 되는데 나머지는 다 지우고 이것만 남겨주면 된다 .

보는것과 같이 만들어 지자마자 인플레이션 되는것을 볼수있다. 

(지금 이 메서드는 프래그먼트 생명주기에 관련된 것인데 생명주기는 중요한것 몇개만 사용하니 뒷부분에 보자 ) 

 

이렇게 인플레이션 된것을 메인 xml에 추가해보자 

 

코드를 보면 fragment를 만들어 주고 거기에 각각의 속상값을 작성해주었는데 

중요하게 봐야할 부분이 name 부분이다. 이 부분엔 추가할 프래그먼트의 주소값을 작성해주면 된다 

 

이렇게 xml을 사용한 프래그먼트 추가를 보았고 이젠 코드를 통한 프래그먼트 추가를 해도록 하겠다 

 

코드로 추가해보기 

xml로 추가한것처럼 프래그먼트를 만들어 주고 넘겨줄 프래그먼트를 인플레이션 해준다 (위랑 똑같아서 코드생략 ) 

 

그리고 나서 메인액티비티에서 작업을 해준다 

public class MainActivity extends AppCompatActivity {

    FragmentManager fragmentManager;
    MainFragment mainFragment;
    MenuFragment menuFragment;

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

        fragmentManager = getSupportFragmentManager(); // 1. 플래그먼트 매니저 호출
        //mainFragment = (MainFragment)fragmentManager.findFragmentById(R.id.mainFragment);
        //미리 xml에 만들어 놓은거라 정적인 방법

        //위 아래 두가지 방법이 있다.
        mainFragment = new MainFragment();
        menuFragment = new MenuFragment();
        //2.트랜젝션 시작 . 추가 (뭐 추가할건지 ) . 수행
        fragmentManager.beginTransaction().add(R.id.container,mainFragment).commit(); 
        // .commit() 은 수행한다라는 의미
    }

코드를 보면 먼저 프래그먼트  1 매니저를 getSupportFragmentManger를 사용해 프래그먼트 매니저를 호출해주었다.

그리고 나서 2 각각의 프래그먼트 클래스를 객체화 시켜주고 3프래그 먼트 매니저로 시작해준것을 볼수 있다. 

여기서 프래그먼트매니저는 액티비티에 추가(add) , 변경(replace) , 삭제(remove) 등으로 사용가능 

팁) 여기서는 getSupportFragmentManager를 사용했지만 getFragmentManager랑 같은 기능이다 하지만 

일반적으로는 예전기능까지 호환되도록 만드는게 좋으므로 getSupportFragmentManager 이거 사용권장 

 

 사용방법을 간단하게 살펴봤는데 다음은 더 복잡한 것을 만들 것이니 집중!! 

프래그먼트는 다양한 프래그먼트를 제공하는데 여기서는 ListFragment 와 DialogFragment 를 사용해보겠다 

ListFragment는 ListView로 화면을 구성할 때 ListView와 관련된 내용만 액티비에서 분리해 Framgment로 구현할 수 있게 만든 클래스 이다. 

 

메인코드 

public class MainActivity extends AppCompatActivity {

    // 사용할 각각의 클래스들
    FragmentManager fragmentManager;
    List_Fragment listFragment;
    ImageFragment imageFragment;
    Dialog_Fragment dialog_fragment;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 2. 매니저와 프래그먼트 설정
        fragmentManager = getSupportFragmentManager();
        listFragment = new List_Fragment();
        imageFragment = new ImageFragment();
        dialog_fragment = new Dialog_Fragment();

        // 3 리스트프래그먼트 와 이미지프래그먼트 추가 해줌
        fragmentManager.beginTransaction().add(R.id.container1, listFragment).commit();
        fragmentManager.beginTransaction().add(R.id.container2,imageFragment).commit();


    }
    //이미지뷰를 변경하기위한 메소드 
    //리스트뷰의 버튼에서 눌린 인트값 받아와 이미지뷰의 메소드 실행 하며 이미지변경
    public void onImageSelected(int position){
        imageFragment.setImageView(position);
    }


    @Override//Back 버튼눌렸을때 실행되는 메소드
    public void onBackPressed() {
        //show 함수를 이용하여 출력해줄수 있다. 다이얼로그 프래그먼트 코드표 확인
        dialog_fragment.show(fragmentManager, null); // 다이얼로그를 보여줘라

        // super.onBackPressed(); 이거 안지우면 본래의 빽프레스 키를 쓰고 있다.

    }
}

다이얼로그 

public class Dialog_Fragment extends DialogFragment {
    @NonNull
    @Override
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
        // 다이얼로그 만드는거랑 똑같음 다이얼로그 참조
        AlertDialog.Builder builder =new AlertDialog.Builder(getActivity());
        builder.setIcon(android.R.drawable.ic_dialog_alert);
        builder.setTitle("종료확인");
        builder.setMessage("이 프로그램 종료 하실라우? ");
        //다이얼로그창에서 오른쪽 버튼 값
        builder.setPositiveButton("확인", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                //프래그먼트를 종료할게 아니라 메인 액티비티를 종료해야하므로
                //메인액티비티를 종요하기 위하여 이렇게 작성
                ((MainActivity)getActivity()).finish();
            }
        });
        //다이얼로그 왼쪽 버튼 값 취소기 때문에 null로 작성해줌
        builder.setNegativeButton("취소",null);
        AlertDialog dialog = builder.create(); // 빌더 추가

        return dialog;

    }
}

리스트프래그먼트

public class List_Fragment extends ListFragment {


    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        String[] datas= {"1이미지", "2이미지", "3이미지"};
        ArrayAdapter<String> adapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_list_item_1,datas);
        setListAdapter(adapter);
    }

    @Override // 리스트에서 어떤 버튼이 눌렸는지 확인을 할수 있는 메소드
    public void onListItemClick(@NonNull ListView l, @NonNull View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
        //position에 위치인덱스 값이 들어있는데 여기서 직접 메소드 실행 불가능하므로 
        // 1. 메인에 있는 메소드실행 
        ((MainActivity)getActivity()).onImageSelected(position);
    }
}

이미지프래그먼트

public class ImageFragment extends Fragment {
    ImageView imageView;
    int imageId[]  = {R.drawable.jeju1,R.drawable.jeju2,R.drawable.jeju3};
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        ViewGroup viewGroup = (ViewGroup)inflater.inflate(R.layout.fragment_image, container, false);
        imageView = viewGroup.findViewById(R.id.imageView);
        return viewGroup;
    }
    // 3 받은 인덱스 값에 따라 이미지 변경해준다
    public void setImageView(int id){
        imageView.setImageResource(imageId[id]);
    }
}

엄청 복잡해 보이지만 중요한 메소드빼고 본다면 사실 지금까지 배운 내용으로 충분이 이해될 코드이다. 

출력결과 

이렇게 버튼을 눌럿을 때 이미지변경도 잘 되고 back 버튼을 눌럿을때 다이얼로그 화면도 잘뜨는걸 볼 수 있다. 

 

자 처음에 프래그먼트는 각각의 화면의 영역을 나누고 분리된 화면들을 유지보수 하기 편하게 한다고 했었다 . 

위 코드들이 한 액티비티에 모여 있었다면 코드를 보기에도 힘들고 나눠져 있기때문에 각각의 관련된 코드들만 있기때문에 개발자의 입장에서 봤을때 더욱 편리한 것이다. 

 

프래그먼트의 생명주기

 

 

오늘도 공부하느라 고생했고~ 지금까지 정리한것만 해도 분량이 어마어마한대 이거 언제다 익히냐... ㅋㅋ 

그래도 개발자가 되는 그날까지 열공!
 

반응형