development

프래그먼트를 사용하여 백 스택 지우기

big-blog 2020. 4. 17. 08:15
반응형

프래그먼트를 사용하여 백 스택 지우기


내 안드로이드 앱을 허니컴으로 포팅했으며 조각을 사용하기 위해 큰 리팩터링을 수행했습니다. 이전 버전에서는 홈 버튼을 눌렀을 때 ACTIVITY_CLEAR_TOP백 스택을 재설정하기 위해 사용했습니다 .

이제 내 응용 프로그램은 여러 조각으로 구성된 단일 활동이므로 홈 버튼을 누르면 내부 조각 중 하나만 바꿉니다. 플래그 startActivity와 함께 사용하지 않고 어떻게 백 스택을 지울 수 ACTIVITY_CLEAR_TOP있습니까?


나는 비슷한 것을 여기에 올렸다.

Joachim의 답변, Dianne Hackborn의 답변 :

http://groups.google.com/group/android-developers/browse_thread/thread/d2a5c203dad6ec42

나는 단지 다음을 사용하여 끝났다.

FragmentManager fm = getActivity().getSupportFragmentManager();
for(int i = 0; i < fm.getBackStackEntryCount(); ++i) {    
    fm.popBackStack();
}

그러나 다음과 같이 사용할 수도 있습니다.

((AppCompatActivity)getContext()).getSupportFragmentManager().popBackStack(String name, FragmentManager.POP_BACK_STACK_INCLUSIVE)

이름이 지정된 상태로 모든 상태가 팝업됩니다. 그런 다음 조각을 원하는 것으로 바꿀 수 있습니다.


@Warpzit의 의견에 대한 답변을 만들고 다른 사람들이 더 쉽게 찾을 수 있도록하기 위해.

사용하다:

fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

모든 관련 당사자에 대한 모든 존중; 얼마나 많은 사람들이 간단한 조각으로 전체 조각 다시 스택을 지울 수 있는지 매우 놀랐습니다.

fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

안드로이드 문서 에 따르면 (논리와 관련 name하여 주장 된 작업 제안서의 "널").

null의 경우, 최상위 상태 만이 팝된다

이제 특정 구현에 대한 지식이 부족하다는 것을 알고 있습니다 (예 : 주어진 시점에 백 스택에있는 항목 수). 잘 정의 된 것을 기대할 때 받아 들여진 대답에 모든 돈을 베팅 할 것입니다 광범위한 장치 및 공급 업체에서의 동작 :

(참고로 이것과 함께 뭔가)

FragmentManager fm = getFragmentManager(); // or 'getSupportFragmentManager();'
int count = fm.getBackStackEntryCount();
for(int i = 0; i < count; ++i) {    
    fm.popBackStack();
}

받아 들여진 대답으로는 충분하지 않았습니다. 나는 사용해야했다 :

FragmentManager fm = getSupportFragmentManager();
int count = fm.getBackStackEntryCount();
for(int i = 0; i < count; ++i) {
    fm.popBackStackImmediate();
}

루프를 사용하지 않고 나를 위해 쉬운 방법으로 작동합니다.

 FragmentManager fragmentManager = getSupportFragmentManager();
 //this will clear the back stack and displays no animation on the screen
 fragmentManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

루프없이 명확한 백 스택

String name = getSupportFragmentManager().getBackStackEntryAt(0).getName();
getSupportFragmentManager().popBackStack(name, FragmentManager.POP_BACK_STACK_INCLUSIVE);

여기서 name 은 addToBackStack () 매개 변수입니다.

getSupportFragmentManager().beginTransaction().
                .replace(R.id.container, fragments.get(titleCode))
                .addToBackStack(name)

방금 추가하고 싶었습니다 :-

다음을 사용하여 백 스택에서 튀어 나옴

fragmentManager.popBackStack ()

트랜잭션에서 조각을 제거하는 것입니다. 화면에서 조각을 제거하지는 않습니다. 따라서 이상적으로는 보이지 않지만 두 개 또는 세 개의 조각이 서로 겹쳐져있을 수 있으며 뒤로 키를 누르면 UI가 어수선하게 쌓일 수 있습니다.

간단한 예를 들면 다음과 같습니다.

fragmentmanager.replace ()를 사용하여 Fragmnet B를로드하는 fragmentA가 있고 addToBackStack을 수행하여이 트랜잭션을 저장 한다고 가정하십시오 . 흐름은 :-

1 단계-> FragmentA-> FragmentB (FragmentB로 옮겼지만 Fragment A는 백그라운드에 있으며 보이지 않음)

이제 fragmentB에서 일부 작업을 수행하고 저장 버튼을 누릅니다. 저장 후 조각 A로 돌아갑니다.

2 단계-FragmentB를 저장하면 FragmentA로 돌아갑니다.

3 단계-> 그래서 일반적인 실수는 ... 조각 B에서 조각 관리자로 조각 관리자 .replace () 조각 B를 수행합니다.

그러나 실제로 일어나는 일은 FragmentB를 대체하여 Fragment A를 다시로드하고 있습니다. 이제 두 개의 FragmentA가 있습니다 (하나는 STEP-1에서, 하나는이 STEP-3에서).

FragmentsA의 두 인스턴스가 서로 겹쳐져 표시되지 않을 수 있지만 거기에 있습니다.

따라서 위의 방법으로 백 스택을 지우더라도 트랜잭션은 지워지지 만 실제 조각은 지워지지 않습니다. 따라서 이상적으로는 저장 버튼을 누르면 fm.popBackStack () 또는 fm.popBackImmediate () 를 수행하여 fragmentA로 돌아 가면됩니다 .

따라서 올바른 Step3-> fm.popBackStack ()은 이미 메모리에있는 fragmentA로 돌아갑니다.


문서를 읽고 프래그먼트 ID가 무엇인지 연구하면 스택 인덱스 인 것처럼 보이므로 다음과 같이 작동합니다.

fragmentManager.popBackStackImmediate(0, FragmentManager.POP_BACK_STACK_INCLUSIVE);

0스택의 맨 아래에 0 ( )이 포함되어 있으므로 스택을 비우면 스택이 지워집니다.

주의 사항 : 위의 프로그램에서 위의 작업을 수행하지만 FragmentManager 설명서에서 실제로 id가 스택 인덱스라고 명시하지 않기 때문에 조금 주저합니다. 그것이 가능하다는 것이 합리적이며 모든 디버그 로그는 그것이 사실임을 드러내지 만 특별한 상황에서는 그렇지 않을 것입니다. 어느 쪽이든이 방법으로 확인할 수 있습니까? 그렇다면 위의 방법이 가장 좋습니다. 그렇지 않은 경우 이것은 대안입니다.

while(fragmentManager.getBackStackEntryCount() > 0) { fragmentManager.popBackStackImmediate(); }

이 방법을 사용하고 Context & Fragment 태그를 전달하여 백 스테이지 조각을 제거해야합니다.

용법

clearFragmentByTag(context, FragmentName.class.getName());



public static void clearFragmentByTag(Context context, String tag) {
    try {
        FragmentManager fm = ((AppCompatActivity) context).getSupportFragmentManager();

        for (int i = fm.getBackStackEntryCount() - 1; i >= 0; i--) {
            String backEntry = fm.getBackStackEntryAt(i).getName();
            if (backEntry.equals(tag)) {
                break;
            } else {
                 fm.popBackStack();
            }
        }
    } catch (Exception e) {
        System.out.print("!====Popbackstack error : " + e);
        e.printStackTrace();
    }
}

나는 이것을 이렇게 작동시켰다.

public void showHome() {
    getHandler().post(new Runnable() {
        @Override
        public void run() {
            final FragmentManager fm = getSupportFragmentManager();
            while (fm.getBackStackEntryCount() > 0) {
                fm.popBackStackImmediate();
            }
        }
    });
}

그것은 나를 위해 노력하고 있습니다, 이것을 시도하십시오 :

public void clearFragmentBackStack() {
        FragmentManager fm = getSupportFragmentManager();
        for (int i = 0; i < fm.getBackStackEntryCount() - 1; i++) {
            fm.popBackStack();
        }
    }

    private void clearBackStack(){
        SupportFragmentManaer fm = getSupportFragmentManager();
        fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
    }

이 메소드를 호출하면 매우 깔끔합니다.

  1. 루프가 필요하지 않습니다.
  2. 조각으로 애니메이션을 사용하는 경우 너무 많은 애니메이션이 표시되지 않습니다. 그러나 루프를 사용합니다.

private boolean removeFragFromBackStack() {
    try {
        FragmentManager manager = getSupportFragmentManager();
        List<Fragment> fragsList = manager.getFragments();
        if (fragsList.size() == 0) {
            return true;
        }
        manager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
        return true;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return false;
}

안녕하세요 ~ https://gist.github.com/ikew0ng/8297033 에서 훨씬 더 나은 솔루션을 찾았습니다.

    /**
 * Remove all entries from the backStack of this fragmentManager.
 *
 * @param fragmentManager the fragmentManager to clear.
 */
private void clearBackStack(FragmentManager fragmentManager) {
    if (fragmentManager.getBackStackEntryCount() > 0) {
        FragmentManager.BackStackEntry entry = fragmentManager.getBackStackEntryAt(0);
        fragmentManager.popBackStack(entry.getId(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
    }
}

참고 URL : https://stackoverflow.com/questions/6186433/clear-back-stack-using-fragments

반응형