Mảnh vỡ của tôi trôi qua Hoạt động
Gặp khó khăn khi giao tiếp với nhau, nó sử dụng Bộ chuyển đổi FragmentPager
Là một lớp trợ giúp triển khai các tab và quản lý tất cả chi tiết sẽ ViewPager
liên kết với TabHost
Đã kết nối. Tôi đã đạt được Bộ chuyển đổi FragmentPager
, giống như dự án mẫu Android Hỗ trợ4Demos Giống như được cung cấp.
Vấn đề chính là khi tôi không có ID cũng như thẻ thì làm cách nào để truy cập Trình quản lý mảnh vỡ
Nhận một đoạn cụ thể? Bộ chuyển đổi FragmentPager
Đoạn đang được tạo và Id và nhãn được tạo tự động.
Tóm tắt vấn đề
LƯU Ý: Trong câu trả lời này tôi sẽ trích dẫn Bộ chuyển đổi FragmentPager
và mã nguồn của nó. Nhưng giải pháp chung cũng có tác dụng với Bộ chuyển đổi FragmentStatePager
.
Nếu bạn đang đọc bài viết này thì có thể bạn đã biết Bộ chuyển đổi FragmentPager
/Bộ chuyển đổi FragmentStatePager
được thiết kế để tạo ra Mảnh vỡ
cho bạnViewPager
, nhưng khi Hoạt động được tạo lại (cho dù thiết bị quay hay hệ thống tắt ứng dụng của bạn để lấy lại bộ nhớ) thì những điều này Mảnh vỡ
sẽ không được tạo lại, nhưng chúng các trường hợp được lấy từ Trình quản lý mảnh vỡ
.Bây giờ hãy cho tôi biếtHoạt động
Cần trích dẫn những điều này Mảnh vỡ
Làm việc trên chúng. bạn không có nhận dạng
hoặc nhãn
Tạo cho những thứ này Mảnh vỡ
bởi vìBộ chuyển đổi FragmentPager
đặt chúng bên trong .vì vậy câu hỏi đặt ra là làm cách nào để có được tài liệu tham khảo về chúng mà không có thông tin này...
Vấn đề với giải pháp hiện tại: Sự phụ thuộc vào mã nội bộ
Nhiều giải pháp tôi đã thấy cho vấn đề này và các câu hỏi tương tự đều dựa vào việc sử dụng các giải pháp hiện có Mảnh vỡ
trích dẫn. gọi FragmentManager.findFragmentByTag()
và bắt chướcthẻ được tạo nội bộ: "android:switcher:" + viewId + ":" + id
.Vấn đề với điều này là bạn đang dựa vào mã nguồn nội bộ, mà như tất cả chúng ta đều biết, mã này không được đảm bảo sẽ giữ nguyên mãi mãi. Các kỹ sư Android của Google có thể dễ dàng quyết định các thay đổi nhãn
cấu trúc sẽ phá vỡ mã của bạn để bạn không thể tìm thấy câu trả lời cho câu hỏi hiện có Mảnh vỡ
thẩm quyền giải quyết.
Các giải pháp thay thế không dựa vào nội bộnhãn
Đây là một ví dụ đơn giản về cách lấy cặp Mảnh vỡ
trích dẫn. phụ thuộc vào Bộ chuyển đổi FragmentPager
Lợi nhuận không phụ thuộc vào nội bộ thẻ
đặt vào Mảnh vỡ
.Điều quan trọng là phải che chắn instantiateItem()
và lưu tài liệu tham khảo trong đóthay vìhiện hữu getItem()
ở giữa.
lớp công khai SomeActivity mở rộng Activity {
mảnh riêng tưA m1stFragment;
riêng tư FragmentB m2ndFragment;
// mã khác trong Hoạt động của bạn...
lớp riêng CustomPagerAdapter mở rộng FragmentPagerAdapter {
// mã khác trong FragmentPagerAdapter tùy chỉnh của bạn...
công khai CustomPagerAdapter(FragmentManager fm) {
siêu(fm);
}
@Ghi đè
công khai Fragment getItem(int vị trí) {
// KHÔNG cố gắng lưu các tham chiếu đến Fragment trong getItem(),
// vì getItem() không phải lúc nào cũng được gọi. Nếu Fragment
// đã được tạo rồi thì nó sẽ được lấy từ FragmentManger
// và không có ở đây (tức là getItem() sẽ không được gọi lại).
chuyển đổi (vị trí) {
trường hợp 0:
trả về FragmentA() mới;
trường hợp 1:
trả về FragmentB() mới;
mặc định:
// Điều này không bao giờ nên xảy ra. Luôn tính đến từng vị trí ở trên
trả về giá trị null;
}
}
// Ở đây cuối cùng chúng ta có thể lưu một cách an toàn một tham chiếu đến mục đã tạo
// Fragment, bất kể nó đến từ đâu (getItem() hoặc
// FragmentManger). Chỉ cần lưu Fragment đã trả về từ
// super.instantiateItem() thành một tham chiếu thích hợp tùy thuộc vào
// trên vị trí ViewPager.
@Ghi đè
Đối tượng công khai instantiateItem(ViewGroup container, int vị trí) {
Fragment createdFragment = (Fragment) super.instantiateItem(container, position);
// lưu tham chiếu thích hợp tùy thuộc vào vị trí
chuyển đổi (vị trí) {
trường hợp 0:
m1stFragment = (FragmentA) createdFragment;
phá vỡ;
trường hợp 1:
m2ndFragment = (FragmentB) createdFragment;
phá vỡ;
}
trả về createdFragment;
}
}
công khai void someMethod() {
// làm việc trên các Fragment được tham chiếu, nhưng trước tiên hãy kiểm tra xem chúng
// thậm chí còn chưa tồn tại, nếu không bạn sẽ nhận được NPE.
nếu (m1stFragment != null) {
// m1stFragment.doWork();
}
nếu (m2ndFragment != null) {
// m2ndFragment.doSomeWorkToo();
}
}
}
hoặcNếu bạn thích sử dụng thẻ
thay vì các biến/cặp thành viên lớp Mảnh vỡ
Bạn cũng có thể lấy trích dẫn củathẻ
phụ thuộc vào Bộ chuyển đổi FragmentPager
Thiết lập theo cách tương tự: LƯU Ý: Điều này không áp dụng cho Bộ chuyển đổi FragmentStatePager
bởi vì nó chưa được thiết lập thẻ
trong khi tạo ra nó Mảnh vỡ
giờ.
@Ghi đè
Đối tượng công khai instantiateItem(ViewGroup container, int vị trí) {
Fragment createdFragment = (Fragment) super.instantiateItem(container, position);
// lấy các thẻ được thiết lập bởi FragmentPagerAdapter
chuyển đổi (vị trí) {
trường hợp 0:
Chuỗi firstTag = createdFragment.getTag();
phá vỡ;
trường hợp 1:
Chuỗi secondTag = createdFragment.getTag();
phá vỡ;
}
// ... lưu các thẻ ở đâu đó để bạn có thể tham khảo chúng sau
trả về createdFragment;
}
Lưu ý rằng phương pháp này không dựa vào việc bắt chước nội bộ nhãn
phụ thuộc vào Bộ chuyển đổi FragmentPager
Thay vào đó, cài đặt hãy sử dụng API thích hợp để truy xuất chúng. Vì vậy ngay cả khi nhãn
Hỗ trợThư viện
Bạn vẫn sẽ được an toàn trước những thay đổi phiên bản trong tương lai.
đừng quênnó phụ thuộc vào bạn Hoạt động
thiết kế, Mảnh vỡ
Công việc bạn đang cố gắng có thể tồn tại hoặc không, vì vậy bạn phải làm vô giá trị
Để giải quyết vấn đề này, hãy kiểm tra trích dẫn của bạn trước khi sử dụng chúng.
Ngoài ra, nếubạn đang sử dụng Bộ chuyển đổi FragmentStatePager
, thì bạn không muốn giữ Mảnh vỡ
Vì bạn có thể có nhiều tài liệu tham khảo cứng nên tài liệu tham khảo cứng sẽ giữ chúng trong bộ nhớ một cách không cần thiết. nhưng tiết kiệm Mảnh vỡ
YếuTham khảo
Tham chiếu các biến dữ liệu thay vì các biến tiêu chuẩn. Như thế này:
WeakReference m1stFragment = new WeakReference(createdFragment);
// ...và truy cập chúng như thế này
Đoạn đầu tiênFragment = m1stFragment.get();
nếu (firstFragment != null) {
// tham chiếu vẫn chưa được xóa; hãy làm việc...
}
Tôi là một lập trình viên xuất sắc, rất giỏi!