관리 메뉴

막내의 막무가내 프로그래밍 & 일상

[안드로이드] 프래그먼트 뒤로가기 했을때 처리 본문

안드로이드/자바 & Previous

[안드로이드] 프래그먼트 뒤로가기 했을때 처리

막무가내막내 2019. 3. 20. 00:03
728x90

출처및 참고 : https://developer.android.com/guide/components/fragments?hl=ko


프래그먼트 관련 코딩을 하다가 프래그먼트는 액티비티와 다르게 onBackPressed()를 오버라이딩을 할 수 없어서 이 메소드에 뒤로가기 관련 이벤트를 처리할 수 없었다.


그래서 당시에 프래그먼트를 띄워줬을 때 뒤로가기를 누르면 현재 띄어진 프래그먼트를 참조하고 있는 Fragment 객체를 프래그먼트 관리자를 통해 remove를 해주고 null로 초기화해줬었다.

밑에처럼 말이다. 참고로 moveinfo는 프래그먼트고 이미 액티비티에서 올라가있는 프래그먼트가 있는데 그 프래그먼트에서 버튼을 누르면 이 moveinfo가 담고있는 프래그먼트가 올라가는 상황이다.

액티비티 내의 오버라이딩하는 onBackPressed()에 구현한거다.

@Override
public void onBackPressed() {
if(movieInfo != null){ //상세정보창 프래그먼트를 킨 상태면 뒤로가기했을 때 해당 프래그먼트를 삭제해줌
getSupportFragmentManager().beginTransaction().remove(movieInfo).commit();
movieInfo = null;
}else {
super.onBackPressed();
}

}



그런데 나중에 안드로이드 개발자문서에서 프래그먼트를 살펴보니깐

이러한게 있었고 이렇게 사용하는게 더 맞다고 생각하고 기억하기위해서 이 글을 적는다.

바로 addToBackStack()이라는 메소드를 사용하는것이다.


프래그먼트 트랜잭션 수행

액티비티에서 프래그먼트를 사용하는 경우 특히 유용한 점은 사용자 상호작용에 응답하여 추가, 제거, 교체 및 다른 작업을 수행할 수 있다는 것입니다. 액티비티에 커밋한 변경 내용의 집합을 트랜잭션이라고 하며, 이것을 수행하려면 FragmentTransaction 내의 API를 사용하면 됩니다. 해당 액티비티가 관리하는 백 스택에 행해진 각 트랜잭션을 저장할 수도 있습니다. 이렇게 하면 사용자가 프래그먼트 변경 내역을 거쳐 뒤로 탐색할 수 있습니다(액티비티를 통과해 뒤로 탐색하는 것과 비슷합니다).

FragmentTransaction의 인스턴스를 FragmentManager로부터 가져오는 방법은 다음과 같습니다.

FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

각 트랜잭션은 동시에 수행하고자 하는 변경 집합입니다. 주어진 트랜잭션에 대해 수행하고자 하는 모든 변경 사항을 설정하려면 add(), remove(), 및 replace()와 같은 메서드를 사용하면 됩니다. 그런 다음, 트랜잭션을 액티비티에 적용하려면 반드시 commit()을 호출해야 합니다.

하지만 commit()을 호출하기 전에 먼저 호출해야 할 것이 있습니다. 바로 addToBackStack()입니다. 이렇게 해야 트랜잭션을 프래그먼트 트랜잭션의 백 스택에 추가할 수 있습니다. 이 백 스택을 액티비티가 관리하며, 이를 통해 사용자가 이전 프래그먼트 상태로 되돌아갈 수 있습니다. 이때 Back 버튼을 누르면 됩니다.

예를 들어 다음은 한 프래그먼트를 다른 것으로 교체하고 이전 상태를 백 스택에 보존하는 방법을 보여줍니다.

// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();

// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction
.replace(R.id.fragment_container, newFragment);
transaction
.addToBackStack(null);

// Commit the transaction
transaction
.commit();

이 예시에서는 newFragment가 현재 레이아웃 컨테이너에서 식별된 프래그먼트(있는 경우)를 R.id.fragment_container ID로 교체합니다. addToBackStack()를 호출함으로써 교체 트랜잭션이 백 스택에 저장되므로, 사용자가 Back 버튼을 눌러 트랜잭션을 되돌리고 이전 프래그먼트를 다시 가져올 수 있습니다.

트랜잭션에 여러 개의 변경을 추가하고(예: 또 다른 add() 또는 remove()), addToBackStack()을 호출하면, commit()을 호출하기 전에 적용된 모든 변경 내용이 백 스택에 하나의 트랜잭션으로 추가되며, Back 버튼을 누르면 모두 한꺼번에 되돌려집니다.

FragmentTransaction에 변경 내용을 추가하는 순서는 중요하지 않습니다. 다만 다음과 같은 예외가 있습니다.

  • commit()을 마지막으로 호출해야 합니다.
  • 같은 컨테이너에 여러 개의 프래그먼트를 추가하는 경우, 이를 추가하는 순서가 이들이 뷰 계층에 나타나는 순서를 결정 짓습니다.

프래그먼트를 제거하는 트랜잭션을 수행하면서 addToBackStack()을 호출하지 않는 경우, 해당 프래그먼트는 트랜잭션이 적용되면 소멸되고 사용자가 이를 되짚어 탐색할 수 없게 됩니다. 반면에 프래그먼트를 제거하면서 addToBackStack()을 호출하면, 해당 프래그먼트는 중단되고 사용자가 뒤로 탐색하면 재개됩니다.

팁: 각 프래그먼트 트랜잭션에 대해 전환 애니메이션을 적용하려면 커밋하기 전에 setTransition()을 호출하면 됩니다.

commit()을 호출해도 그 즉시 트랜잭션을 수행하지는 않습니다. 그보다는, 액티비티의 UI 스레드("주요" 스레드)를 스레드가 할 수 있는 한 빨리 이 트랜잭션을 수행하도록 일정을 예약하는 것에 가깝습니다. 하지만 필요한 경우 UI 스레드로부터 executePendingTransactions()를 호출하면 commit()이 제출한 트랜잭션을 즉시 실행할 수 있습니다. 트랜잭션이 다른 스레드의 작업에 대한 종속성이 아니라면 굳이 이렇게 해야만 하는 것은 아닙니다.



꼭 기억하도록 하자.



[공감과 댓글은 큰 힘이됩니당]




728x90
Comments