programing

FragmentPagerAdapter로 다시 이동-> 조각이 비어 있습니다.

nasanasas 2021. 1. 7. 08:02
반응형

FragmentPagerAdapter로 다시 이동-> 조각이 비어 있습니다.


pagerFragment백 스택에 추가되고 표시 되는 조각 (이라고 부르겠습니다 )이 있습니다. 그것은을 보유하고 viewPager로모그래퍼 FragmentPagerAdapter. FragmentPagerAdapterA와 B (하자의 말) 두 조각을 보유

먼저 조각을 추가하면 잘 작동합니다.

조각 A에는 한 번 클릭하면 조각 (C)이 백 스택에 추가되는 버튼이 있습니다.

문제는 이것입니다. 해당 조각 (C)을 추가 한 다음 다시 클릭하면 pagerAdapter이 비어 있고 내부 조각을 볼 수 없습니다.

해킹을 사용하고 pagerFragments 의 하위 조각 (A 및 B)을 파괴하면 onDestroyView()이 해킹을 사용하고 싶지는 않지만 문제가 해결됩니다.

문제가 무엇인지 아이디어가 있습니까?


나는 같은 문제가 있었다. 나를위한 해결책은 간단했습니다.

onCreateView에서 다음을 수행했습니다.

// Create the adapter that will return a fragment for each of the three
// primary sections of the app.
mSectionsPagerAdapter = new SectionsPagerAdapter(getActivity()
    .getSupportFragmentManager());

SectionPageAdapter는 다음과 같습니다.

class SectionsPagerAdapter extends FragmentPagerAdapter {
...
}

getSupportFragmentManager를 다음으로 변경 한 후

mSectionsPagerAdapter = new SectionsPagerAdapter(getChildFragmentManager());

작동하기 시작했습니다! 도움이 되었기를 바랍니다.


ViewPager가 PagerFragment 내부에 있기 때문에 중첩 조각을 사용하는 것처럼 들립니다. FragmentPagerAdapter의 생성자에 getChildFragmentManager ()를 전달 했습니까? 그렇지 않다면.

FragmentStatePagerAdapter가 필요하다고 생각하지 않지만 Fragment 상태 저장 및 복원을 처리하기 때문에 한 번 시도해 보겠습니다. onDestroyView () 해킹이 작동한다는 사실은 FragmentStatePagerAdapter를 원할 수 있다고 생각하게 만듭니다.

또한 FragmentPagerAdapter가 Fragment를 추가하는 방식과 관련이있을 수 있습니다. FragmentPagerAdapter는 백 스택에 조각을 추가하지 않습니다. ViewPager에 10 개 이상의 페이지가 추가되었고 사용자가 페이지를 스 와이프했다고 상상해보십시오. 사용자는 앱에서 빠져 나가기 위해 11 번을 눌러야합니다.

이 게시물과 관련이있을 수도 있습니다 : Nested Fragments 및 The Back Stack .

또한 Fragment C를 무엇에 추가하고 있는지 잘 모르겠습니다. ViewPager와 동일한 컨테이너에 추가하고 있습니까?

적어도 조사 할 몇 가지 옵션이 있습니다. 이러한 상황에서 저는 Android SDK 소스 코드로 디버그하여 동작의 원인을 확인하고 싶습니다. AOSP 소스를 잡고 SDK 소스로 프레임 워크 / 지원 및 프레임 워크 /베이스를 추가 하는 것이 좋습니다 . 그것이 무슨 일이 일어나고 있는지 이해하고 일이 작동 할 때까지 임의의 변경을 피하는 유일한 방법입니다.


우리 프로젝트에서도 문제에 직면했습니다. 근본 원인은 FragmentPagerAdapter가 작동하는 방식입니다.

FragmentPagerAdapter는 현재 필요하지 않은 Fragment를 뷰에서 분리하기 만하고 FragmentManager에서 제거하지는 않습니다. Fragment를 다시 표시하고 싶을 때 그는 ViewPager의 뷰 ID와 어댑터 getItemId (position) 호출에서 반환 된 ID에서 생성 된 태그를 사용하여 FragmentManager에 여전히 Fragment가 포함되어 있는지 확인합니다. Fragment를 찾으면 FragmentManager의 업데이트 트랜잭션 내에서 해당 View에 Fragment를 첨부하도록 예약합니다. 이런 식으로 조각을 찾지 못한 경우에만 어댑터 getItem (position) 호출을 사용하여 새 조각을 만듭니다!

FragmentPagerAdapter가있는 ViewPager를 포함하는 Fragment의 문제점은 포함하는 Fragment가 백 스택에 배치 될 때 FragmentManager의 내용이 정리되지 않는다는 것입니다. 포함 된 Fragment가 백 스택에서 돌아 오면 새 뷰가 생성되지만 FragmentManager에는 여전히 이전 뷰에 연결된 조각이 포함되어 있으며 기존 조각의 첨부는 더 이상 작동하지 않습니다.

이 문제를 제거하는 가장 쉬운 방법은 중첩 된 조각을 피하는 것입니다. :)

두 번째로 쉬운 방법은 다른 게시물에서 이미 언급했듯이 FragmentPagerAdapter에 ChildFragmentManager를 사용하는 것입니다.이 방법은 컨테이너 조각의 수명주기 동안 적절하게 업데이트됩니다.

두 옵션이 모두 불가능한 프로젝트 (현재의 프로젝트)가 있으므로 여기에 하위 조각의 hashCode를 해당 위치에있는 조각의 항목 ID로 사용하여 임의의 FragmentManager와 함께 작동하는 솔루션을 게시했습니다. 어댑터 내의 모든 위치에 대한 모든 조각을 저장하는 대가가 따릅니다.

public class MyPagerAdapter extends FragmentPagerAdapter {

private static int COUNT = ...;
private final FragmentManager fragmentManager;
private Fragment[] subFragments = new Fragment[COUNT];
private FragmentTransaction cleanupTransaction;

public MyPagerAdapter(FragmentManager fragmentManager) {
    super(fragmentManager);
    this.fragmentManager = fragmentManager;
}

@Override
public Fragment getItem(int position) {
    return getSubFragmentAtPosition(position);
}

@Override
public int getCount() {
    return COUNT;
}

@Override
public long getItemId(int position) {
    return getSubFragmentAtPosition(position).hashCode();
}

//The next three methods are needed to remove fragments no longer used from the fragment manager
@Override
public void startUpdate(ViewGroup container) {
    super.startUpdate(container);
    cleanupTransaction = fragmentManager.beginTransaction();
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    super.destroyItem(container, position, object);
    cleanupTransaction.remove((Fragment) object);
}

@Override
public void finishUpdate(ViewGroup container) {
    super.finishUpdate(container);
    cleanupTransaction.commit();
}

private Fragment getSubFragmentAtPosition(int position){
    if (subFragments[position] == null){
        subFragments[position] = ...;
    }
    return subFragments[position];
}

}


사용 getChildFragmentManager()대신에 getSupportFragmentManager(). 잘 작동합니다.

참조 URL : https://stackoverflow.com/questions/17672779/navigating-back-to-fragmentpageradapter-fragments-are-empty

반응형