Sự khác biệt giữa FragmentPagerAd CHƯƠNG và FragmentStatePagerAdOG là gì?


375

Sự khác biệt giữa FragmentPagerAdaptervà là FragmentStatePagerAdaptergì?

Về FragmentPagerAdapterhướng dẫn của Google cho biết:

Phiên bản máy nhắn tin này là tốt nhất để sử dụng khi có một số ít các mảnh tĩnh thường được phân trang thông qua, chẳng hạn như một bộ các tab. Đoạn của mỗi trang mà người dùng truy cập sẽ được giữ trong bộ nhớ, mặc dù hệ thống phân cấp chế độ xem của nó có thể bị hủy khi không hiển thị. Điều này có thể dẫn đến việc sử dụng một lượng bộ nhớ đáng kể vì các trường hợp phân đoạn có thể giữ một lượng trạng thái tùy ý. Đối với bộ trang lớn hơn, hãy xem xét FragmentStatePagerAdapter.

Và về FragmentStatePagerAdapter:

Phiên bản máy nhắn tin này hữu ích hơn khi có một số lượng lớn các trang, hoạt động giống như chế độ xem danh sách. Khi người dùng không nhìn thấy các trang, toàn bộ đoạn của họ có thể bị hủy, chỉ giữ trạng thái lưu của đoạn đó. Điều này cho phép máy nhắn tin giữ bộ nhớ ít hơn nhiều được liên kết với mỗi trang được truy cập so với FragmentPagerAdapterchi phí có khả năng cao hơn khi chuyển đổi giữa các trang.

Vậy là tôi chỉ có 3 mảnh. Nhưng tất cả chúng là các mô-đun riêng biệt với một lượng lớn dữ liệu.

Fragment1xử lý một số dữ liệu (mà người dùng nhập) và chuyển nó qua hoạt động Fragment2, đây chỉ là một cách đơn giản ListFragment. Fragment3cũng là một ListFragment.

Vì vậy, câu hỏi của tôi là : Tôi nên sử dụng bộ chuyển đổi nào? FragmentPagerAdapterhay FragmentStatePagerAdapter?


2
Tôi nghĩ rằng chỉ có 3 Fragment đủ điều kiện để bạn sử dụng FragmentPagerAdOG. Các tab cho các mảnh này có thể sẽ được hiển thị đồng thời.
IgorGanapolsky

2
bài đăng này đã lưu 5-6 giờ của tôi vì tôi sử dụng sai loại Adaptor
Nantaphop

1
Trả lời cho câu hỏi này ném thêm một câu hỏi stackoverflow.com/questions/9156406/
Piyush Kukadiya

FragmentPagerAdapterFragmentStatePagerAdapternhưng là FragmentStateAdaptergì?
the_prole

Câu trả lời:


292

Giống như các tài liệu nói, hãy nghĩ về nó theo cách này. Nếu bạn đã làm một ứng dụng như một trình đọc sách, bạn sẽ không muốn tải tất cả các đoạn vào bộ nhớ cùng một lúc. Bạn muốn tải và hủy Fragmentskhi người dùng đọc. Trong trường hợp này bạn sẽ sử dụng FragmentStatePagerAdapter. Nếu bạn chỉ hiển thị 3 "tab" không chứa nhiều dữ liệu nặng (như Bitmaps), thì FragmentPagerAdaptercó thể rất phù hợp với bạn. Ngoài ra, hãy nhớ rằng ViewPagertheo mặc định sẽ tải 3 đoạn vào bộ nhớ. Cái đầu tiên Adapterbạn đề cập có thể phá hủy Viewhệ thống phân cấp và tải lại khi cần, thứ hai Adapterchỉ lưu trạng thái của nó Fragmentvà phá hủy hoàn toàn nó, nếu người dùng sau đó quay lại trang đó, trạng thái được lấy ra.


Tôi có nhiều Nút và TextView trong Fragment1 và ListView để tạo các mục động trong Fragment2 và Fragment3. Bạn có nghĩ rằng nên sử dụng FragmentStatePagerAdOG và lưu trữ tất cả dữ liệu trong Activity, chuyển nó đến Fragment qua Bundle không?
AlexMomotov

2
@AlexMomotov Lượt xem trong bố cục của Fragment không liên quan gì đến việc lựa chọn FragmentStatePagerAd CHƯƠNG. Câu hỏi ở đây là số lượng Mảnh vỡ sẽ được phân trang.
IgorGanapolsky

1
Vì vậy, cơ bản không có gì có lợi cho FragmentPagerAdapterviệc sử dụng nó.
Tomasz Mularchot

3
@Tomasz lợi thế của FragmentPagerAdapterviệc chuyển đổi giữa các mảnh có thể nhanh hơn nhiều, vì các Fragmentđối tượng thực tế không cần phải được xây dựng lại mỗi lần. Mặt khác, điều này sẽ kết thúc bằng việc sử dụng nhiều bộ nhớ hơn giữ các đối tượng mảnh trong bộ nhớ.
Richard Le Mesurier

Tôi có 3 tab / trang (mỗi trang hiển thị một WebView), vì vậy đã sử dụng FragmentPagerAd CHƯƠNG . Tuy nhiên, trang cuối cùng vẫn được vẽ lại khi tôi vuốt qua nó từ trang đầu tiên. Để giải quyết điều này, tôi đã sử dụng viewPager.setOffscreenPageLimit(2).
ban-geengineering

131
  • FragmentPagerAdapterlưu trữ toàn bộ đoạn trong bộ nhớ và có thể tăng chi phí bộ nhớ nếu sử dụng một lượng lớn các mảnh vỡ ViewPager.

  • Ngược lại với anh chị em của nó, FragmentStatePagerAdapterchỉ lưu trữ các mảnh vỡ đã lưu và phá hủy tất cả các mảnh vỡ khi chúng mất tập trung.

  • Do đó, FragmentStatePagerAdapternên được sử dụng khi chúng ta phải sử dụng các đoạn động, như các đoạn có widget, vì dữ liệu của chúng có thể được lưu trữ trong savedInstanceState. Ngoài ra, nó sẽ không ảnh hưởng đến hiệu suất ngay cả khi có số lượng lớn các mảnh.

  • Ngược lại anh chị em của nó FragmentPagerAdapternên được sử dụng khi chúng ta cần lưu trữ toàn bộ đoạn trong bộ nhớ.

  • Khi tôi nói toàn bộ đoạn được giữ trong bộ nhớ, điều đó có nghĩa là các thể hiện của nó sẽ không bị phá hủy và sẽ tạo ra một bộ nhớ trên đầu. Do đó, chỉ nên sử dụng FragmentPagerAdapterkhi có số lượng mảnh vỡ thấp ViewPager.

  • Sẽ tốt hơn nữa nếu các mảnh đó là tĩnh, vì chúng sẽ không có số lượng lớn các đối tượng mà các thể hiện của chúng sẽ được lưu trữ.

Để chi tiết hơn,

FragmentStatePagerAd CHƯƠNG:

  • với FragmentStatePagerAdapter, đoạn không cần thiết của bạn bị hủy. Giao dịch được cam kết loại bỏ hoàn toàn đoạn đó khỏi hoạt động của bạn FragmentManager.

  • Trạng thái FragmentStatePagerAdapterxuất phát từ thực tế là nó sẽ cứu được mảnh vỡ của bạn Bundletừ savedInstanceStatekhi nó bị phá hủy. Khi người dùng điều hướng trở lại, đoạn mới sẽ được khôi phục bằng trạng thái của mảnh.

FragmentPagerAd CHƯƠNG:

  • Bằng cách so sánh FragmentPagerAdapterkhông có gì thuộc loại này. Khi mảnh vỡ không còn cần thiết. FragmentPagerAdaptercác cuộc gọi detach(Fragment)trên giao dịch thay vì remove(Fragment).

  • Điều này phá hủy quan điểm của mảnh vỡ nhưng để lại trường hợp của mảnh vỡ còn tồn tại trong FragmentManager. Vì vậy, các mảnh vỡ được tạo ra FragmentPagerAdapterkhông bao giờ bị phá hủy.


2
Tại sao bạn có 2 câu trả lời?
Jared Burrows

lợi ích của việc giữ toàn bộ các mảnh vỡ trong bộ nhớ là gì?
Tomasz Mularchot

4
@Tomek: nếu đoạn tiếp theo đã được khởi tạo (ví dụ: FragmentPagerAd CHƯƠNG), nó sẽ sẵn sàng hiển thị khi bạn vuốt vào nó, vì vậy hoạt hình vuốt sẽ mượt mà hơn. Với FragmentStatePagerAd CHƯƠNG, trường hợp đoạn tiếp theo có thể không tồn tại cho đến khi bạn vuốt sang nó và nếu đó là một đoạn lớn đắt tiền để tạo, bạn có thể thấy một đoạn trong hình ảnh động. Đó là một câu hỏi về hiệu suất so với mức tiêu thụ bộ nhớ.
Dalbergia

1
@Jared Burrows bcoz một chỉ là AnswerText đó là tốt cho câu trả lời nhỏ và tĩnh và thứ hai là AnswerStateText đó là câu trả lời lớn hơn và năng động
Đơn giản Fellow

48

Dưới đây là vòng đời nhật ký của mỗi phân đoạn trong ViewPagerđó có 4 phân đoạn vàoffscreenPageLimit = 1 (default value)

FragmentStatePagerAd CHƯƠNG

Chuyển đến Fragment1 (hoạt động khởi chạy)

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

Chuyển đến Fragment2

Fragment3: onCreateView
Fragment3: onStart

Chuyển đến Fragment3

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

Chuyển đến Fragment4

Fragment2: onStop
Fragment2: onDestroyView
Fragment2: onDestroy

FragmentPagerAdOG

Chuyển đến Fragment1 (hoạt động khởi chạy)

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

Chuyển đến Fragment2

Fragment3: onCreateView
Fragment3: onStart

Chuyển đến Fragment3

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

Chuyển đến Fragment4

Fragment2: onStop
Fragment2: onDestroyView

Kết luận : FragmentStatePagerAdaptergọi onDestroykhi Fragment được khắc phục offscreenPageLimittrong khi FragmentPagerAdapterkhông.

Lưu ý : Tôi nghĩ rằng chúng ta nên sử dụng FragmentStatePagerAdaptercho một trang ViewPagercó nhiều trang vì nó sẽ tốt cho hiệu suất.

Ví dụ về offscreenPageLimit:

Nếu chúng ta đến Fragment3, nó sẽ hủy bỏ Fragment1 (hoặc Fragment5 nếu có) bởi vì offscreenPageLimit = 1. Nếu chúng ta thiết lập offscreenPageLimit > 1sẽ không phá hủy.
Nếu trong ví dụ này, chúng tôi đặt offscreenPageLimit=4, không có sự khác biệt giữa việc sử dụng FragmentStatePagerAdapterhoặc FragmentPagerAdaptervì Fragment không bao giờ gọi onDestroyViewonDestroykhi chúng tôi thay đổi tab

Bản demo của Github tại đây


Thật là một cách kết luận tuyệt vời!
Rahul Rastogi

lời giải thích hay
gourav singhal

1
Giải thích tốt đẹp. Bạn đã nói rằng sử dụng FragmentStatePagerAdOG khi có nhiều trang là tốt cho hiệu suất. Ý bạn là nó tốt cho việc tiết kiệm bộ nhớ? Mục tiêu theo tôi hiểu là bảo toàn bộ nhớ trong trường hợp có thể xảy ra nhiều trường hợp Fragment - vì vậy hiệu suất là lợi ích tiềm ẩn; mục tiêu rõ ràng là bảo tồn bộ nhớ
Hatzil

38

Một cái gì đó không được nói rõ ràng trong tài liệu hoặc trong các câu trả lời trên trang này (mặc dù được ngụ ý bởi @Naruto), là nó FragmentPagerAdaptersẽ không cập nhật các Mảnh vỡ nếu dữ liệu trong Mảnh vỡ thay đổi vì nó giữ Mảnh vỡ trong bộ nhớ.

Vì vậy, ngay cả khi bạn có số lượng Fragment giới hạn để hiển thị, nếu bạn muốn có thể làm mới các đoạn của mình (ví dụ: bạn chạy lại truy vấn để cập nhật listView trong Fragment), bạn cần sử dụng FragmentStatePagerAd CHƯƠNG.

Toàn bộ quan điểm của tôi ở đây là số lượng Mảnh vỡ và chúng có giống nhau hay không không phải luôn luôn là khía cạnh quan trọng để xem xét. Dù mảnh vỡ của bạn có năng động hay không cũng là chìa khóa.


Vì vậy, giả sử tôi có 2 đoạn, 1 recyclerview trong đoạn A, khi tôi nhấp vào một mục, nó thay đổi nội dung của đoạn B, giả sử tôi làm FragB.setText ("blablabla"). Tôi nên sử dụng pagerthen nhà nước?
Ced

Không chắc chắn nhưng tôi sẽ nói có. Chỉ cần thử cả hai, thật dễ dàng và nhanh chóng để thay đổi mã của bạn từ mã này sang mã khác.
JDenais

@JDenais Bạn có chắc điều này đúng không? Tôi đang sử dụng FragmentPagerAdaptertrong hoạt động của mình sử dụng ViewPager để hiển thị hai đoạn - trong đó mỗi đoạn chứa một danh sách. Danh sách đầu tiên của tôi được gọi là "Tất cả các báo cáo" và danh sách thứ hai là "Báo cáo yêu thích". Trong danh sách đầu tiên, nếu tôi nhấn vào biểu tượng ngôi sao cho báo cáo, nó sẽ cập nhật cơ sở dữ liệu để chuyển trạng thái yêu thích của báo cáo đó. Sau đó tôi vuốt qua và tôi thấy thành công báo cáo này trong giao diện người dùng của danh sách thứ hai. Vì vậy, có thể các phiên bản được lưu trong bộ nhớ nhưng trong một số trường hợp (ví dụ: của tôi), nội dung sẽ thực sự cập nhật tốt cho FragmentPagerAd CHƯƠNG
ban-Geoengineering

14

FragmentPagerAdapterlưu trữ dữ liệu trước đó được lấy từ bộ điều hợp trong khi FragmentStatePagerAdapterlấy giá trị mới từ bộ điều hợp mỗi khi nó được thực thi.


4

FragmentStatePagerAd CHƯƠNG = Để chứa một số lượng lớn các mảnh vỡ trong ViewPager. Vì bộ điều hợp này sẽ phá hủy đoạn đó khi người dùng không nhìn thấy và chỉ lưu lạiInstanceState của đoạn đó để tiếp tục sử dụng. Bằng cách này, một lượng bộ nhớ thấp được sử dụng và hiệu suất tốt hơn được phân phối trong trường hợp các đoạn động.


1

FragmentPagerAdOG : đoạn của mỗi trang mà người dùng truy cập sẽ được lưu trong bộ nhớ, mặc dù chế độ xem sẽ bị hủy. Vì vậy, khi trang được hiển thị lại, chế độ xem sẽ được tạo lại nhưng thể hiện đoạn không được tạo lại. Điều này có thể dẫn đến một lượng đáng kể bộ nhớ được sử dụng. FragmentPagerAdOG nên được sử dụng khi chúng ta cần lưu trữ toàn bộ đoạn trong bộ nhớ. FragmentPagerAdOG gọi tách (Fragment) trên giao dịch thay vì loại bỏ (Fragment).

FragmentStatePagerAd CHƯƠNG : thể hiện đoạn bị hủy khi người dùng không nhìn thấy, ngoại trừ trạng thái đã lưu của đoạn. Điều này dẫn đến việc chỉ sử dụng một lượng nhỏ Bộ nhớ và có thể hữu ích để xử lý các tập dữ liệu lớn hơn. Nên được sử dụng khi chúng ta phải sử dụng các đoạn động, như các đoạn có widget, vì dữ liệu của chúng có thể được lưu trong saveInstanceState. Ngoài ra, nó sẽ không ảnh hưởng đến hiệu suất ngay cả khi có số lượng lớn các đoạn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.