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.