默認情況下,`ViewPager` 會預加載左右相鄰 Fragment,導致 `onCreateView` 提前執行。需求是:**僅當用戶點擊/滑動到該頁時才加載數據,且支持二次進入刷新**。
利用 `setUserVisibleHint` (舊 API) 或 `FragmentTransaction` 的 `setMaxLifecycle` (新 API) 控制生命周期,配合標誌位實現首次可見時加載。
public class LazyFragment extends Fragment {
private boolean isLoaded = false; // 標誌位:是否已加載
private boolean isVisible = false; // 標誌位:是否對用戶可見
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
isVisible = isVisibleToUser;
tryLoadData();
}
@Override
public void onResume() {
super.onResume();
tryLoadData(); // 配合 ViewPager offscreenPageLimit 使用
}
private void tryLoadData() {
if (isVisible && !isLoaded && getView() != null) {
loadData(); // 真正的網絡請求/數據庫查詢
isLoaded = true; // 防止重複加載
}
}
// 提供公開方法供下拉刷新調用
public void refresh() {
isLoaded = false;
tryLoadData();
}
private void loadData() { /* 具體加載邏輯 */ }
}
**強烈建議**使用 `SwipeRefreshLayout` 替代「二次點擊刷新」:**符合用戶習慣**、**交互自然**、**支持加載動畫**。
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipeRefresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RecyclerView /> <!-- 或 ListView, ScrollView -->
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
swipeRefresh.setOnRefreshListener(() -> {
refresh(); // 調用上述 refresh() 方法
// 模擬網絡延遲後關閉動畫
swipeRefresh.postDelayed(() -> swipeRefresh.setRefreshing(false), 2000);
});
// 重要:解決 RecyclerView 滑動衝突
swipeRefresh.setRefreshing(false); // 初始關閉