FragmentPagerAdapter를 사용하는 ViewPager의 조각은 두 번째로 볼 때 비어 있습니다.


98

기본보기에서 다른 조각을 여는 하단에 탭이있는 조각 인터페이스가 있습니다.

항목 목록 인 특정 조각이 하나 있습니다. 사용자가이 목록의 항목 중 하나를 선택하면 이전 조각의 목록에있는 모든 항목 사이를 가로로 스크롤하는 뷰 페이저가 포함 된 다른 조각이 열립니다. 이것은 훌륭하게 작동합니다.

뷰 페이저는 FragmentPagerAdapter를 사용하여 항목을 표시합니다.

문제는 사용자가 목록에서 항목을 선택하고 본 다음 탭 막대의 버튼을 눌러 목록으로 돌아간 다음 다른 항목을 선택할 때 발생합니다. 두 번째로 항목을 선택하면 뷰 페이저 대신 빈 화면이 나타납니다. 이 경우 LogCat에 오류가 발생하지 않습니다.

뷰 페이저가 처음에만 나타나는 이유는 무엇입니까?

FragmentPagerAdapter:

public class ViewPagerAdapter extends FragmentPagerAdapter {
    Cursor mCursor;

    public ViewPagerAdapter(FragmentManager fm, Cursor c) {
        super(fm);
        mCursor = c;
    }

    public void changeCursor(Cursor c) {
        mCursor = c;
        this.notifyDataSetChanged();
    }

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

    @Override
    public Fragment getItem(int position) {
        mCursor.moveToPosition(position);
        return TeamCardFragment.newInstance(mCursor, position);
    }
}

PagerFragment:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    Bundle bundle = getArguments();
    mCursorPosition = bundle.getInt(TeamCardCommon.BUNDLE_KEY_CURSOR_POSITION);

    View mView = inflater.inflate(R.layout.team_card_master, container, false);
    mViewPager = (ViewPager)mView.findViewById(R.id.team_card_master_view_pager);

    mAdapter = new ViewPagerAdapter(getFragmentManager(), cursor);
    new setAdapterTask().execute();

    return mView;
}

private class setAdapterTask extends AsyncTask<Void, Void, Void> {
    protected Void doInBackground(Void... params) {
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        mViewPager.setAdapter(mAdapter);
        mViewPager.setCurrentItem(mCursorPosition);
    }
}

답변:


221

나는 같은 문제가 있었다. 내 PageAdapter의 부모 클래스를에서 변경하여 "두 번째"표시 문제 android.support.v4.app.FragmentPagerAdapterandroid.support.v4.app.FragmentStatePagerAdapter해결했습니다 ViewPager!


2
농담하지? 더 이상이 코드가 없습니다. 그렇지 않으면 테스트 할 것입니다. 아마도이 대답은 다른 사람에게 도움이 될 것입니다.
howettl 2011

10
무슨 남자! 며칠 동안이 솔루션을 찾고있었습니다! 고마워요, 매력처럼 작동합니다. 하지만 내 안의 개발자는 그 변화가 어떤 영향을 미치는지 묻고 있습니다. 그 전에 왜 StatePagerAdapter에서 작동하지 않았다 왜 내 말은
아난드 Sainath

1
또한 당신은 @Override public int getItemPosition (Object object) {return POSITION_NONE; }
Helin Wang

1
나를 위해 일했습니다. 여기에 링크가 있습니다. 모든 차이를 만드는 조각 상태를 저장하는 것 같습니다. developer.android.com/reference/android/support/v4/app/…
Tjaart 2014

1
우연의 일치입니다. 정답은 @Daniel F의 것입니다. 여하튼, 여기서 덧글의 편의에 대한 차이 FragmentPagerAdapterFragmentStatePagerAdapter, 후자는 더 많은 적합하면서보다 몇 페이지에 적합한 전 존재에, 그것은 메모리에 단편 따라서 페이지 스위치 최상의 성능을 갖는 모든 유지 페이지는 조각을 파괴하고 상태 만 유지하며 메모리 효율성은 더 높지만 페이지 전환시 약간 느립니다.
Cristina De Rito

87

나는 부모 조각에서 로 대체 getFragmentManager()하여 이것을 해결했습니다 getChildFragmentManager(). 이 상위 프래그먼트는 생성자에 프래그먼트 관리자가 필요한 페이징 가능 (슬라이드 가능) 프래그먼트를 포함하기 위해 android.support.v4.app.FragmentPagerAdapter 를 인스턴스화했습니다 . 이 생성자에 반환 값을 전달했습니다 getChildFragmentManager().

hackbod의 링크는 핵심 ( https://developer.android.com/about/versions/android-4.2.html#NestedFragments ) 이었으며이 게시물은 Fragments 내의 Fragments 에서 발견되었습니다.

조각을 중첩하려면 getChildFragmentManager()조각을 추가하려는 Fragment를 호출 하면됩니다. 이렇게하면 조각 트랜잭션을 생성하기 위해 최상위 수준 활동에서 일반적으로 수행하는 것처럼 사용할 수있는 FragmentManager가 반환됩니다.


고맙습니다 ... 나는 fragmentpageradapter가 포함 된 onresume () 후 슬라이딩 탭 뷰를 다시 인스턴스화하려고 시도하는 비슷한 문제가있었습니다 ... 내가 사용한 튜토리얼은 2016 년에 있었고 여전히 그것을 얻기 위해 fragmentstatepageradapter로 변경해야했습니다. 작업. 왜 내가 알았 으면 좋겠어.
Nerdy Bunz

이 답변은 내 시간을 많이 절약했습니다. 사용하는 것만으로 FragmentStatePagerAdapter는 여기에서 묻는 질문이 해결되지 않기 때문 입니다. 와 함께 FragmentStatePagerAdapter부모 조각 YourAdapter adapter = new YourAdapter (getChildFragmentManager()); 을 추가해야합니다
MMK

17

나를 위해 뷰 페이저에서 이것을 호출해야했습니다.

myViewPager.setSaveFromParentEnabled(false);

뷰 페이저가 새로 고쳐지지 않고 조각이 있어야하는 빈 흰색 화면 만 본 문제가있었습니다. getChildFragmentManager를 전달했지만 도움이되지 않았습니다.


1
왜 세상에서이 일을 했습니까? 이것은 내 문제를 해결했지만 이유가 전혀 없습니다.
ClayHerendeen

이제 코드에서 제거했습니다. 조각 관리자가 문제를 일으켰습니다. getchildfragmentmanager와 getfragmentmanager 간 전환 시도
j2emanue

나는 이미 그것을 시도했습니다. 스 와이프를 비활성화 한 ViewPager가있는 중첩 탭이 있습니다. 나는 이것이 열악한 디자인이라는 것을 알고 있지만 클라이언트는 내 것이 아닙니다. 최상위 탭 모음에 childFragmentManager를 사용하고 있습니다. 하위 수준 탭바 / 뷰 페이저로 전환해도 문제가 해결되지 않는 것 같습니다. 나는 그것이 작동하고 있기 때문에 지금은 setSaveFromParentEnabled (false)를 고수 할 것이라고 가정합니다.
ClayHerendeen

최신 지원 라이브러리를 사용하고 있습니까
j2emanue

2
지난 2 일 동안 동일한 문제가 발생했습니다. 귀하의 솔루션이 저에게 효과적이었습니다. 감사 !
brijexecon

11

AppBarLayout 및 ViewPager와 함께 CoordinatorLayout을 사용하는 매우 특별한 경우에 해결 된 것은 AppBarLayout xml 속성에서 android : fitsSystemWindows = "true"를 제거하는 것 입니다.

이유를 묻지 마십시오. 나는 그것이 약간 우스꽝스럽게 들리고 상관 관계가 없어야한다는 것을 알고 있지만 이미 어댑터에서 getChildFragmentManager ()를 사용하고 있었기 때문에 문제를 일으키는 유일한 줄은이 한 줄이었습니다. 나는 이것을 찾기 위해 하루 종일 내 코드를 디버깅하는 데 보냈으므로 다른 사람이 시간을 절약하기를 바랍니다.


3
오 이런 ... 난이 문제로 거의 항복 할 뻔 했어. 당신은 내 끔찍한 하루를 만들었습니다! Geez Google, WTF는 AppBarLayout에 문제가 있습니까? 나는 거의 백 페이지를 보았고 운 없이이 문제를 해결하기 위해 디버깅하는 데 많은 시간을 보냈습니다. 마침내 귀하의 의견으로 문제를 해결할 수 있었던 것에 대해 정말 감사드립니다. 감사합니다! 추신 : 필사적이어서 AOSP에서 이슈를 만들었습니다. code.google.com/p/android/issues/… XD
Guillem Roca

힌트 주셔서 감사합니다. 적어도 문제 해결에 도움이되었습니다. 이제 우리는 그것을 전체 화면을 만들기위한 옵션을 찾기 위해 노력하고있다
Paresh Mayani

당신은 생명의 은인입니다! 나는 왜 내가이 문제를 겪고 있는지 전혀 몰랐고 여전히 왜 그것이 효과가 있는지 전혀 알지 못했습니다!
nandu

10

내가로부터 어댑터를 변경하는 동일한 문제가 있었다 FragmentPagerAdapterFragmentStatePagerAdaptergetFragmentManager()에 부모 조각에를getChildFragmentManager()

그 이유 FragmentStatePagerAdapter는 페이지가 표시되지 않는 동안 조각의 저장된 상태 만 유지하므로 방문한 각 페이지와 관련된 메모리와 많은 페이지를 저장하는 데 도움이됩니다. 이렇게하면 조각간에 전환하는 동안 오버 헤드가 줄어 듭니다.


4

넣어 시도 setOffscreenPageLimit (int limit)부모 ViewPager.

mViewPager.setOffscreenPageLimit(totalPages-1);

이것은 나를 위해 매력처럼 작동했습니다.

제 경우에는 내부에 조각이있었습니다 TabLayout 에 .ViewPager.

그리고 ViewPager그 조각 안에 또 하나 . 처음에는 모두 잘 작동하지만 탭을 변경하고 다시 돌아 오면 일부 조각이 비어 있습니다.


1
좋은 대답입니다. 도움이되었습니다.
Thirumalvalavan

2

이것은 당신을 도울 것입니다.

    viewPager.setOffscreenPageLimit(position);

1

뷰 페이저 항목을 조각이 아닌 표준 뷰로 다시 구현하고 그에 따라 어댑터를 변경하여이 문제를 해결했습니다.


당신은 함수 isViewFromObject (보기보기, 개체 개체) 제거 시도 할 수 있습니다
미나 새미

더 나은 방법이 있어야합니다 .... : / 비록 내가 안드로이드를 더 많이 파고 들수록 덜 성숙하다는 것을 깨닫습니다.
StackOverflowed

1
중첩 된 조각은 지원되지 않으므로 표준보기로 다시 구현하는 것이 좋은 방법 인 것 같습니다.
Sylphe 2012 년

비슷한 문제로 어려움을 겪고 있습니다. FragmentAdapter 대신 PagerAdapter를 사용해 보았지만 여전히 동일한 문제가 발생합니다. 제발 도와주세요!
Gaurav Arora

중첩 된 조각을 사용하려면이 답변에서 제공 한 어댑터를 사용할 수 있습니다. stackoverflow.com/questions/7700226/…
Slickelito

1

두 번째로 빈 화면이있는 Xamarin Android 에서 동일한 문제가 발생했습니다 . 다음을 설정하면 문제가 해결되었습니다 .

viewPager.SaveFromParentEnabled = false;

0

앱이 최소화되고 나중에 호출 될 때이 오류가 발생하는 경우에도 어댑터를 초기화 할 수 있습니다.

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    Bundle bundle = getArguments();
    mCursorPosition = bundle.getInt(TeamCardCommon.BUNDLE_KEY_CURSOR_POSITION);
    View mView = inflater.inflate(R.layout.team_card_master, container, false);
    mViewPager = (ViewPager)mView.findViewById(R.id.team_card_master_view_pager);
    initViewPagerAdapter();
    return mView;
}
private void initViewPagerAdapter(){
    mAdapter = new ViewPagerAdapter(getFragmentManager(), cursor);
    new setAdapterTask().execute();
}

@Override
public void onResume(){
    super.onResume();
    initViewPagerAdapter();
}

0

두 번째로 호출기 어댑터를 호출했을 때 자식 뷰가 NullPointerException을 반환했습니다. 그리고 FragmentStatePagerAdapter에서 어댑터를 변경하면 내 문제도 해결됩니다.


0

변경 FragmentPagerAdapterFragmentStatePagerAdapter 사용 getChildFragmentManager()하는 대신getFragmentManager()

getChildFragmentManager()-문서에 따르면이 Fragment 내부에 Fragment를 배치하고 관리하기위한 전용 FragmentManager를 반환하기 때문입니다. 한편 getFragmentManager()이 활동과 관련된 프래그먼트와 상호 작용하기 위해 FragmentManager를 반환합니다.


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