10

Tôi đang gặp vấn đề khá lớn và tôi không hoàn toàn hiểu những gì đang xảy ra. Tôi đang phát triển một ứng dụng có sử dụng Fragments (từ thư viện hỗ trợ) và đang sử dụng FragmentTransaction.replace() để đặt Fragment mới vào stack phía sau và thay thế cái cũ. Mã trông như sau:Android Fragment View State Loss Khi sử dụng FragmentTransaction.replace()

FragmentManager fm = getSupportFragmentManager(); 
FragmentTransaction ft = ft.beginTransaction(); 
// Animations in my res/anim folder 
ft.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left, R.anim.slide_in_left, R.anim.slide_out_right); 
ft.replace(R.id.fragment_container, newFragment, tag); 
ft.addToBackStack(null); 
ft.commit(); 

Điều này thành công trong việc thay thế đoạn của tôi. Vấn đề của tôi là như sau. Trong một Fragment, tôi có một danh sách các mục được xây dựng từ đầu vào của người dùng. Bây giờ, khi người dùng nhấp vào tiếp theo và sau đó nhấp vào nút quay lại (để quay lại danh sách), danh sách sẽ trống vì chế độ xem bị hủy. Bây giờ, tôi đã lưu ý những điều sau đây:

  1. onSaveInstanceState không được gọi. Tôi tin rằng điều này là bởi vì điều đó chỉ được gọi khi hoạt động của phụ huynh nói với nó. Dựa trên các tài liệu: "Có nhiều tình huống mà một đoạn có thể bị rách nát (như khi được đặt trên ngăn xếp sau không hiển thị giao diện người dùng), nhưng trạng thái của nó sẽ không được lưu cho đến khi hoạt động sở hữu thực sự cần lưu trạng thái của nó ". Rõ ràng, thực hiện một thay thế trên FragmentTransaction không phải là một trong những lần đó. Có ai có xác nhận về điều này hoặc một lời giải thích tốt hơn?
  2. setOnRetainInstanceState (true) không hữu ích trong trường hợp này. Một lần nữa, tôi tin rằng điều này có liên quan đến thông tin từ các tài liệu: "Kiểm soát liệu một cá thể mảnh được giữ lại trong quá trình tạo lại Hoạt động (chẳng hạn như từ thay đổi cấu hình)". Tôi không thực hiện bất kỳ hành động nào trong việc tạo lại hoạt động để điều này không được sử dụng.

Vì vậy, tôi đoán câu hỏi chính của tôi là: có cách nào để bảo toàn trạng thái Chế độ xem (chỉ cần giữ lại Phân đoạn) khi sử dụng replace? Có FragmentTransaction.add(), nhưng có một vài vấn đề với điều này là tốt. Một là hoạt ảnh xuất cảnh không được thực hiện, do đó hoạt ảnh không chính xác. Một thứ khác nữa là mảnh vỡ mới mà đoạn cũ (cái đang được đưa vào trạng thái không nhìn thấy được) vẫn có thể nhấp được. Ví dụ, nếu tôi có một ListFragment, và tôi đặt một mảnh nội dung trên đầu trang đó bằng cách sử dụng add, tôi vẫn có thể nhấp vào các mục danh sách trong ListFragment.

Trả lời

2

Không thể nhìn thấy mã của các đoạn của bạn, đây là một chút đoán, nhưng trước đây tôi đã gặp phải sự cố tương tự này và tôi nhận thấy rằng đặt lại bộ điều hợp trong ListFragment trong onViewStateRestored dường như làm các trick.

public void onViewStateRestored (Bundle savedInstanceState) 
{ 
    super.onViewStateRestored (savedInstanceState); 
    setListAdapter(new ArrayAdapter(Activity, R.layout.nav_item, objects)); 
} 

Đó là lạ xem xét các tài liệu nói rằng phương pháp này được gọi là sau khi onActivityCreated nhưng trước khi onStart. Nhưng có vẻ như nó cũng được gọi vào những lúc khác bởi vì khi giao dịch phân đoạn gần đây nhất được bật ra khỏi ngăn xếp phía sau, phương thức này được gọi trước khi đoạn được thay thế trước đó được hiển thị. Hoạt động sở hữu các mảnh vỡ đã không bị tạm dừng hoặc bị che khuất theo bất kỳ cách nào, do đó, theo các tài liệu onViewStateRestored không nên được gọi vì chỉ các mảnh đã được sửa đổi. Nhưng điều này dường như vẫn hoạt động.

2

Có vẻ như bạn chỉ cần đảm bảo bạn đã triển khai đúng cách trênCreateView và onDestroyView. Tình huống bạn đang mô tả dường như chỉ ra rằng khi phân mảnh danh sách được đặt trên ngăn xếp lại (do kết quả của giao dịch thay thế), Android đang gọi onDestroyView để giải phóng một số tài nguyên. Tuy nhiên, nó dường như đã không phá hủy các mảnh danh sách bởi vì khi bạn quay trở lại bạn đang nhận được trở lại cùng một ví dụ của đoạn.

Giả sử điều này hoàn toàn đúng, khi người dùng nhấn trở lại Android sẽ gọi onCreateView. Bất kỳ trạng thái nào mà bạn đã lưu trữ trong các biến cá thể của fragment vẫn nên ở đó và tất cả những gì bạn cần làm là duyệt lại chế độ xem ...có lẽ đặt bộ điều hợp trên ListView hoặc bất kỳ thứ gì.

Ngoài ra, hãy đảm bảo gọi lại onSaveInstanceState() của bạn thực sự lưu bất kỳ trạng thái cá thể nào mà bạn cần để tạo lại chế độ xem. Bằng cách đó, nếu mảnh vỡ thực sự bị phá hủy hoàn toàn, FragmentManager có thể khôi phục lại trạng thái khi nó cần phải rời bỏ đoạn sau đó.

Các vấn đề liên quan