已實現 ListView 下拉刷新,需在頁面打開時**自動觸發**下拉刷新動畫與數據加載,無需用戶手動操作。
| 方案 | 優點 | 缺點 | 推薦 |
|---|---|---|---|
| 直接調用刷新方法 | 簡單、無副作用、可控 | 無下拉動畫 | ⭐⭐⭐⭐⭐ |
| 模擬觸摸事件 | 有真實動畫效果 | 依賴 Instrumentation 權限、坐標硬編碼、跨版本兼容性差 | ⭐⭐ |
| 調用 SwipeRefreshLayout.setRefreshing(true) | 標準 API、自動顯示動畫 | 需使用官方 SwipeRefreshLayout | ⭐⭐⭐⭐⭐ |
public class MyListFragment extends ListFragment implements SwipeRefreshLayout.OnRefreshListener {
private SwipeRefreshLayout swipeRefreshLayout;
private MyAdapter adapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_list, container, false);
swipeRefreshLayout = view.findViewById(R.id.swipe_refresh);
swipeRefreshLayout.setOnRefreshListener(this);
// ...
return view;
}
@Override
public void onResume() {
super.onResume();
// 頁面可見時自動觸發刷新
swipeRefreshLayout.post(() -> {
swipeRefreshLayout.setRefreshing(true); // 顯示動畫
onRefresh(); // 執行刷新邏輯
});
}
@Override
public void onRefresh() {
// 異步加載數據
loadData(() -> {
adapter.notifyDataSetChanged();
swipeRefreshLayout.setRefreshing(false); // 隱藏動畫
});
}
}
// 需權限:
// 僅系統應用/簽名應用可獲取,普通 App 無法使用
Instrumentation instrumentation = new Instrumentation();
// 按下
instrumentation.sendPointerSync(MotionEvent.obtain(
SystemClock.uptimeMillis(),
SystemClock.uptimeMillis(),
MotionEvent.ACTION_DOWN,
500, 200, 0 // x, y 坐標需根據 ListView 位置計算
));
// 移動 (模擬下拉)
instrumentation.sendPointerSync(MotionEvent.obtain(
SystemClock.uptimeMillis(),
SystemClock.uptimeMillis(),
MotionEvent.ACTION_MOVE,
500, 400, 0
));
// 抬起
instrumentation.sendPointerSync(MotionEvent.obtain(
SystemClock.uptimeMillis(),
SystemClock.uptimeMillis(),
MotionEvent.ACTION_UP,
500, 400, 0
));
// 如果用第三方庫 (如 SmartRefreshLayout)
smartRefreshLayout.autoRefresh(); // 一鍵自動刷新,含動畫
// 或手動觸發
smartRefreshLayout.setEnableRefresh(true);
smartRefreshLayout.triggerRefresh();
自動刷新 = 顯示動畫標誌 + 執行業務邏輯,不要為了動畫引入系統級風險。