FragmentPagerAdapter getItem이 호출되지 않았습니다.


123

FragmentPagerAdapter에서 조각을 재사용 할 수 없습니다 .. destroyItem () 메서드를 사용하여 조각을 삭제하지만 여전히 getItem ()을 다시 호출하지 않습니다 .. 이미지가 2-3 개이므로 FragmentStatePagerAdapter 대신 FragmentPagerAdapter를 사용하고 있습니다.

public class ExamplePagerAdapter extends FragmentPagerAdapter {

    ArrayList < String > urls;
    int size = 0;
    public ExamplePagerAdapter(FragmentManager fm, ArrayList < String > res) {
        super(fm);
        urls = res;
        size = urls.size();
    }

    @Override
    public int getCount() {
        if (urls == null) {
            return 0;
        } else {
            return size;
        }

    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        FragmentManager manager = ((Fragment) object).getFragmentManager();
        FragmentTransaction trans = manager.beginTransaction();
        trans.remove((Fragment) object);
        trans.commit();
    }

    @Override
    public Fragment getItem(int position) {

        Fragment fragment = new FloorPlanFragment();
        Bundle b = new Bundle();
        b.putInt("p", position);
        b.putString("image", urls.get(position));
        Log.i("image", "" + urls.get(position));
        fragment.setArguments(b);
        return fragment;
    }
}

그리고 FragmentActivity에서

pager.setAdapter(new ExamplePagerAdapter(getSupportFragmentManager(), res2)); 

3
당신이 지나친 특별한 이유가 destroyItem()있습니까? 그것은 필요하지 않습니다.
CommonsWare

다시 초기화하려면 FragmentStatePagerAdapter를 사용하여 재정의 할 때도 호출 super.destroyItem (container, position, object);
faiziii

답변:


306

키스 답변 :

간단한 사용 FragmentStatePagerAdapter 대신 FragmentPagerAdapter .

나는 대답을 얻었습니다 .. 처음에는 매우 어리석은 실수를하고 있기 때문에이 질문을 삭제하려고 생각했지만이 대답은 대신 FragmentPagerAdapter사용 하는 것과 동일한 문제에 직면 한 사람을 도울 것입니다 FragmentStatePagerAdapter.

@BlackHatSamurai가 댓글에서 언급했듯이 :

이것이 작동하는 이유 FragmentStatePagerAdapter는 사용되지 않는 조각으로 파괴 되기 때문 입니다. FragmentPagerAdapter하지 않습니다.


감사합니다 .Ur 답변이 많이 도움이되었습니다.
Priya

1
또 다른 '나도'가되기 싫어! 게시하지만 그래>. <질문을 삭제하지 않아서 감사합니다.
폴 루이즈

34
이것이 작동하는 이유는 FragmentStatePagerAdapter가 사용되지 않는 Fragment로 파괴되기 때문입니다. FragmentPagerAdapter는 그렇지 않습니다.
BlackHatSamurai

3
특정 문제를 검색하는 동안 이것을 발견 할 수있는 사람들을위한 향후 참고 용입니다. FragmentPagerAdapter 및 FragmentStatePagerAdapter 모두에서 읽습니다. 이유에 따라 다르게 작동하며 특정 용도에 따라 다른 것이 필요할 수 있습니다.
Chris Stewart

2
@najibputhawala 저는 FragmentStatePagerAdapter를 사용했지만 여전히 같은 문제에 직면 해 있습니다. 의 getItem ()가 호출되지 않습니다
sam_k

168

를 사용 하면 뷰 페이저에서 자식 조각에 대해 호출되지 않는 FragmentStatePagerAdapter유사한 문제인 내 문제가 완전히 해결 onCreateView되지 않았습니다. 실제로하고 내 중첩 FragmentPagerAdapter또 다른 내부Fragment 그러므로이 FragmentManager그들 모두를 통해 공유 된을 따라서 오래된 조각의 인스턴스를 유지. 수정은 대신 내 호스트 조각 getChildFragmentManager의 생성자에의 인스턴스를 공급하는 것 FragmentPagerAdapter입니다. 뭔가 ...

FragmentPagerAdapter adapter = new FragmentPagerAdapter(getChildFragmentManager());

getChildFragmentManager()메서드는 조각을 통해 액세스 할 수 FragmentManager있으며 중첩 조각이 필요한 상황을 위해 해당 조각에 대한 개인 정보 를 반환하기 때문에 저에게 효과적이었습니다. 나는 이것이 나와 같은 문제를 겪고있을 수있는 누군가를 돕기를 바랍니다!

  • 그러나 getChildFragmentManager()최소 API 버전 을 사용하려면 최소한이어야 17 (4.2)하므로 기어에 렌치가 생길 수 있습니다. 물론 지원 라이브러리 v4의 조각을 사용하는 경우 괜찮습니다.

25
이것은 정답입니다. 문제는 다른 조각에 중첩 된 조각이 getFragmentManager () 대신 getChildrenFragmentManager ()를 사용해야하기 때문입니다.
shihpeng

정말 감사합니다.이 답변을 찾는 데 영원히 걸렸습니다!
Shpongoloid 2015-08-13

@shihpeng에 동의합니다. 정답이되어야합니다.
Raymond Lukanta 2015 년

이것은 나를위한 해결책이었습니다. 답변을 제출해 주셔서 감사합니다
user3734429

문서는 실제로 이것을 워크 스루에서 호출해야합니다. ViewPager가 조각 내에로드되는 것은 매우 현실적입니다. 이 답변을 게시 해 주셔서 감사합니다.
근무

7

우세하다 long getItemId (int position)

FragmentPagerAdapter를 사용하여 생성 한 조각을 캐시합니다 getItem. 나는 전화 notifyDataSetChanged() getItem를받지 않은 후에도 같은 문제에 직면했다 .

이것은 실제로 버그가 아니라 기능입니다. getItemId조각을 올바르게 다시 사용할 수 있도록 재정의해야합니다 . 조각을 제거하고 있으므로 위치가 변경됩니다. 문서에서 언급했듯이 :

long getItemId (int position)

주어진 위치에있는 항목의 고유 식별자를 반환합니다.

기본 구현은 주어진 위치를 반환합니다. 항목의 위치가 변경 될 수있는 경우 하위 클래스가이 메서드를 재정의해야합니다.

각 조각에 고유 한 ID를 제공하면 완료됩니다.

를 사용 FragementStatePagerAdapter하거나 반환 POSITION_NONE하는 int getItemPosition (Object object)것은 잘못되었습니다. 캐싱을 얻지 못할 것입니다.


이것은 정답이었습니다. 조각에 대해 다른 ID를 제공하고 조각을 제거해야하는 경우 반환하도록 getItemId조정 해야했습니다. 그것에 대한 열거 형 플래그가 있습니다. 그 후에 호출됩니다. getItemPositionPOSITION_NONEgetItem
Murat Karagöz

+50에 대해 @ MuratKaragöz에게 감사드립니다 :)
vedant

5

@kanika와 @ Jraco11이 게시 한 작업을 수행했지만 여전히 문제가있었습니다.

그래서 많은 변경 후에 저에게 효과가있는 것을 발견했고 다음 코드를 FragmentPagerAdapter에 추가했습니다.

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }

내가 읽은 내용에 따르면 getItemPositionViewPager 에 항목을 새로 고칠 지 여부 를 알리고 표시되는 위치의 항목이 변경되지 않은 경우 업데이트를 방지하는 데 사용됩니다 .


2

두 가지 시나리오가 있습니다. 1.) 모든 호출기에 대해 동일한 레이아웃이 있습니다.이 경우 PagerAdapter로 사용자 지정 어댑터를 확장하고 단일 레이아웃을 반환하는 것이 더 좋습니다.

2.) 모든 호출기에 대해 다른 레이아웃이 있습니다.이 경우 FragmentStatePagerAdapter로 사용자 지정 어댑터를 확장하고 모든 호출기에 대해 서로 다른 조각을 반환하는 것이 더 좋습니다.


2

메서드 getItem()는 새 항목을 만드는 데만 사용됩니다. 일단 생성되면이 메서드는 호출되지 않습니다. 어댑터에서 사용중인 통화 항목을 가져와야하는 경우 다음 방법을 사용하십시오.

pagerAdapter.instantiateItem(viewPager, TAB_POS)

0

탭 레이아웃에 리스너를 설정하면 리스너 tabLayout.setOnTabSelectedListener배열 대신 하나의 리스너에 대한 공간 만 있기 때문에 이것이 호출되지 않는 것으로 나타났습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.