FragmentPagerAdapter와 FragmentStatePagerAdapter의 차이점은 무엇입니까?


374

차이점은 무엇이며 FragmentPagerAdapter그리고 FragmentStatePagerAdapter?

소개 FragmentPagerAdapter구글의 가이드는 말한다 :

이 버전의 호출기는 일련의 탭과 같이 일반적으로 더 많은 정적 조각이 페이징 될 때 사용하기에 가장 좋습니다. 사용자가 방문하는 각 페이지의 조각은 메모리에 유지되지만보기 계층 구조는 보이지 않을 때 파괴 될 수 있습니다. 프래그먼트 인스턴스가 임의의 양의 상태를 유지할 수 있기 때문에 상당한 양의 메모리를 사용할 수 있습니다. 더 큰 페이지 세트의 경우을 고려하십시오 FragmentStatePagerAdapter.

그리고 약 FragmentStatePagerAdapter:

이 버전의 호출기는 목록보기처럼 작동하는 많은 페이지가있을 때 더 유용합니다. 사용자에게 페이지가 표시되지 않으면 전체 조각이 삭제되어 해당 조각의 저장된 상태 만 유지됩니다. 따라서 페이저는 페이지 FragmentPagerAdapter간에 전환 할 때 잠재적으로 더 많은 오버 헤드가 발생하는 것과 비교하여 방문한 각 페이지와 관련된 메모리를 훨씬 적게 유지할 수 있습니다 .

그래서 나는 단지 3 개의 조각이 있습니다. 그러나 모두 대량의 데이터가있는 별도의 모듈입니다.

Fragment1(사용자 입력)를 일부 데이터로 처리하고, 활동을 통해 전달 Fragment2단순한 인 ListFragment. Fragment3또한입니다 ListFragment.

그래서 내 질문은 : 어떤 어댑터를 사용해야합니까? FragmentPagerAdapter또는 FragmentStatePagerAdapter?


2
3 개의 Fragments 만 있으면 FragmentPagerAdapter를 사용할 수 있다고 생각합니다. 이 조각에 대한 탭은 모두 동시에 표시 될 것입니다.
— IgorGanapolsky

2
이 게시물은 잘못된 유형의 어댑터를 사용하여 5-6 시간을 절약했습니다.
— Nantaphop

1
이 질문에 대한 답변이 하나 더 질문 stackoverflow.com/questions/9156406/…
— Piyush Kukadiya

거기 FragmentPagerAdapter하고 FragmentStatePagerAdapter있지만, 무엇인가 FragmentStateAdapter?
— the_prole

답변:


291

문서가 말했듯이, 이런 식으로 생각하십시오. 책 리더와 같은 응용 프로그램을 수행하는 경우 모든 조각을 한 번에 메모리에로드하지 않을 것입니다. Fragments사용자가 읽을 때로드하고 파괴하려고 합니다. 이 경우을 사용 FragmentStatePagerAdapter합니다. 그냥 무거운 데이터 (등의 많은 포함하지 않는 3 "탭"을 표시하는 경우 Bitmaps), 다음 FragmentPagerAdapter잘 맞게 수 있습니다. 또한 ViewPager기본적으로 3 개의 프래그먼트를 메모리에로드합니다. 첫 번째로 Adapter언급 한 View계층 구조는 필요할 때 다시로드하고 다시로드 할 수 있으며 두 번째 계층 Adapter은 상태를 저장 Fragment하고 완전히 파괴합니다. 사용자가 해당 페이지로 돌아 오면 상태가 검색됩니다.


Fragment1 및 ListView에 Fragment2 및 Fragment3에서 동적으로 항목을 생성하는 여러 개의 단추 및 TextView가 있습니다. FragmentStatePagerAdapter를 사용하고 모든 데이터를 Activity에 저장하고 번들을 통해 Fragments에 전달하는 것이 좋습니다.
— AlexMomotov

2
Fragment의 레이아웃에서 @AlexMomotov 뷰는 FragmentStatePagerAdapter 선택과 관련이 없습니다. 여기서 질문은 페이징 될 조각의 양입니다.
— IgorGanapolsky

1
따라서 기본적으로 FragmentPagerAdapter그것을 사용하는 것이 유리 합니다.
— Tomasz Mularczyk

3
@Tomasz의 장점은 FragmentPagerAdapter실제 Fragment객체를 매번 다시 작성할 필요가 없기 때문에 프래그먼트 간 전환이 훨씬 빨라질 수 있다는 것 입니다. 반면에, 이것은 조각 객체를 메모리에 유지하는 더 많은 메모리를 사용하게됩니다.
— Richard Le Mesurier

3 개의 탭 / 페이지 (각각 WebView가 표시됨)가 있으므로 FragmentPagerAdapter를 사용했습니다 . 그러나 첫 페이지에서 스 와이프하면 마지막 페이지가 다시 그려집니다. 이 문제를 해결하기 위해을 사용했습니다 viewPager.setOffscreenPageLimit(2).
— 금지 지리 공학

131
  • FragmentPagerAdapter전체 조각을 메모리에 저장하고에서 많은 양의 조각을 사용하면 메모리 오버 헤드가 증가 할 수 ViewPager있습니다.

  • 그와는 반대로 형제 FragmentStatePagerAdapter의 savedInstanceState 만 저장하고 포커스를 잃으면 모든 조각을 삭제합니다.

  • 따라서 FragmentStatePagerAdapter데이터가에 저장 될 수 있기 때문에 위젯이있는 조각과 같은 동적 조각을 사용해야 할 때 사용해야합니다 savedInstanceState.

  • 반대로 FragmentPagerAdapter전체 조각을 메모리에 저장해야 할 때 형제를 사용해야합니다.

  • 전체 조각이 메모리에 보관되어 있다고 말하면 인스턴스가 파괴되지 않고 메모리 오버 헤드가 생성됩니다. 따라서에 FragmentPagerAdapter대한 조각 수가 적은 경우에만 사용하는 것이 좋습니다 ViewPager.

  • 프래그먼트가 정적 인 경우 인스턴스가 저장되는 많은 양의 객체가 없기 때문에 훨씬 좋습니다.

더 자세하게

FragmentStatePagerAdapter :

  • 를 사용 FragmentStatePagerAdapter하면 불필요한 조각이 파괴됩니다. 트랜잭션은 활동에서 조각을 완전히 제거하기 위해 노력합니다 FragmentManager.

  • 의 상태는 FragmentStatePagerAdapter그것이 당신의 조각의 밖으로 절약 할 수 있다는 사실에서 유래 Bundle에서을 savedInstanceState은 사용자를 탐색 다시 destroyed.When 때 새로운 조각은 조각의 상태를 사용하여 복원 할 것입니다.

FragmentPagerAdapter :

  • 비교 FragmentPagerAdapter에 의해 종류의 아무것도하지 않습니다. 조각이 더 이상 필요하지 않을 때. 대신 거래를 FragmentPagerAdapter호출 detach(Fragment)합니다 remove(Fragment).

  • 이것은 살아의에게 조각의보기 만 잎 조각의 인스턴스를 파괴 FragmentManager에서 만든 조각 .SO FragmentPagerAdapter파괴되지 않습니다.


2
왜 2 개의 답변이 있습니까?
— Jared Burrows

전체 조각을 메모리에 유지하면 어떤 이점이 있습니까?
— Tomasz Mularczyk

4
@Tomek : 다음 프래그먼트가 이미 인스턴스화되어 있으면 (예 : FragmentPagerAdapter) 스 와이프 할 때 렌더링 할 준비가되어 스 와이프 애니메이션이 더 부드러워집니다. FragmentStatePagerAdapter를 사용하면 스 와이프하여 스 와이프 할 때까지 다음 프래그먼트 인스턴스가 존재하지 않을 수 있습니다. 성능 대 메모리 소비의 문제입니다.
— Dalbergia

1
하나는 그냥 bcoz 버로우 @Jared AnswerText 작고 정적 인 답변을 좋은 다른 인 AnswerStateText 더 큰 동적 답변입니다
— 간단한 연구원

48

다음은 ViewPager4 개의 조각이있는 각 조각의 로그 수명주기입니다.offscreenPageLimit = 1 (default value)

FragmentStatePagerAdapter

Fragment1 (시작 활동)으로 이동

Fragment1: onCreateView
Fragment1: onStart
Fragment2: onCreateView
Fragment2: onStart

조각 2로 이동

Fragment3: onCreateView
Fragment3: onStart

조각 3으로 이동

Fragment1: onStop
Fragment1: onDestroyView
Fragment1: onDestroy
Fragment1: onDetach
Fragment4: onCreateView
Fragment4: onStart

조각 4로 이동

Fragment2: onStop
Fragment2: onDestroyView
Fragment2: onDestroy

FragmentPagerAdapter

Fragment1 (시작 활동)으로 이동

Fragment1: onCreateView
Fragment1: onStart
Fragment2: onCreateView
Fragment2: onStart

조각 2로 이동

Fragment3: onCreateView
Fragment3: onStart

조각 3으로 이동

Fragment1: onStop
Fragment1: onDestroyView
Fragment4: onCreateView
Fragment4: onStart

조각 4로 이동

Fragment2: onStop
Fragment2: onDestroyView

결론 : 파편이 극복 되지 않은 상태 에서 FragmentStatePagerAdapter호출 onDestroy하십시오 . offscreenPageLimitFragmentPagerAdapter

참고 : 나는 우리가 사용한다고 생각 FragmentStatePagerAdapterA에 대한 ViewPager있기 때문에 좋은 성능을위한 것입니다 페이지를 많이 가지고있다.

예 의 offscreenPageLimit:

우리가 Fragment3에 가면, 그것은 것입니다 (있는 경우 또는 Fragment5) Fragment1을 detroy 때문에 offscreenPageLimit = 1. 우리가 설정 offscreenPageLimit > 1하면 파괴 되지 않습니다 .
이 예에서 우리는offscreenPageLimit=4 , 사용하는 사이에 다른이 없다 FragmentStatePagerAdapter거나 FragmentPagerAdapter조각이 호출하지 않기 때문에 onDestroyView그리고 onDestroy우리는 탭을 변경하는 경우는

여기 Github 데모


그런 훌륭한 결론입니다!
— Rahul Rastogi

좋은 설명
— gourav singhal

1
좋은 설명입니다. 많은 페이지를 가질 때 FragmentStatePagerAdapter를 사용하는 것이 성능에 좋다고 말했습니다. 메모리 절약에 적합하다는 의미입니까? 내가 이해하는 목표는 가능한 많은 Fragment 인스턴스의 경우 메모리를 보존하는 것이므로 성능은 암묵적인 이점입니다. 명백한 목표는 기억을 보존하는 것입니다
— Hatzil

38

@Naruto가 암시하더라도 문서 나이 페이지의 답변에서 명시 적으로 언급되지 않은 것은 FragmentPagerAdapter 되지 않은 부분은 프래그먼트를 메모리에 유지하기 때문에 프래그먼트의 데이터가 변경되면 프래그먼트를 업데이트하지 않습니다.

따라서 표시 할 프래그먼트 수가 제한되어 있어도 프래그먼트를 새로 고치려면 (예 : 프래그먼트에서 listView를 업데이트하기 위해 쿼리를 다시 실행하는 경우) FragmentStatePagerAdapter를 사용해야합니다.

필자의 요점은 단편의 수와 이들이 유사한 지 여부가 항상 고려해야 할 주요 측면은 아니라는 것입니다. 조각이 동적인지 여부도 중요합니다.


따라서 조각 A에 2 개의 fragments, recyclerview가 1 개 있다고 가정하고 항목을 클릭하면 조각 B의 내용이 변경됩니다 (fragB.setText ( "blablabla")). 상태 pagerthen을 사용해야합니까?
— Ced

확실하지 않지만 나는 그렇습니다. 두 가지를 모두 시도해보십시오. 어쨌든 코드를 하나에서 다른 코드로 변경하는 것이 매우 쉽고 빠릅니다.
— JDenais

@JDenais 이것이 맞습니까? 내가 사용하고 FragmentPagerAdapter각 조각은 목록을 포함 - 두 조각을 보여주기 위해 ViewPager를 사용하여 내 활동. 첫 번째 목록은 "모든 보고서"이고 두 번째 목록은 "즐겨 찾기 보고서"입니다. 첫 번째 목록에서 보고서의 별표 아이콘을 누르면 데이터베이스가 업데이트되어 해당 보고서의 즐겨 찾기 상태가 전환됩니다. 그런 다음 스 와이프하면 두 번째 목록의 UI에이 보고서가 표시됩니다. 그래서 어쩌면 인스턴스가 메모리에 있지만 어떤 경우에는 (예를 들어, 내) 내용이 실제로 FragmentPagerAdapter에 대한 벌금을 업데이트합니다에 보관
— 금지 - 지구 공학

14

FragmentPagerAdapter어댑터에서 페치 된 이전 데이터를 저장하고 FragmentStatePagerAdapter실행될 때마다 어댑터에서 새 값을 가져옵니다 .


4

FragmentStatePagerAdapter = ViewPager에 많은 조각을 수용합니다. 이 어댑터는 프래그먼트가 사용자에게 보이지 않고 프래그먼트의 savedInstanceState 만 계속 사용하기 위해 프래그먼트를 삭제합니다. 이런 식으로 동적 조각의 경우 적은 양의 메모리가 사용되고 더 나은 성능이 제공됩니다.


1

FragmentPagerAdapter : 사용자가 방문하는 각 페이지의 조각은 메모리에 저장되지만보기는 손상됩니다. 따라서 페이지가 다시 표시되면보기는 다시 작성되지만 프래그먼트 인스턴스는 다시 작성되지 않습니다. 이로 인해 상당한 양의 메모리가 사용될 수 있습니다. FragmentPagerAdapter는 전체 조각을 메모리에 저장해야 할 때 사용해야합니다. FragmentPagerAdapter는 트랜잭션에서 remove (Fragment) 대신 detach (Fragment)를 호출합니다.

FragmentStatePagerAdapter : 프래그먼트의 저장된 상태를 제외하고 프래그먼트 인스턴스는 사용자에게 보이지 않으면 파기됩니다. 결과적으로 적은 양의 메모리 만 사용하게되며 더 큰 데이터 세트를 처리하는 데 유용 할 수 있습니다. 데이터가 savedInstanceState에 저장 될 수 있으므로 위젯이있는 조각과 같은 동적 조각을 사용해야 할 때 사용해야합니다. 또한 조각 수가 많더라도 성능에 영향을 미치지 않습니다.

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