如何用SwipeToRefresh组件刷新Fragment?现有代码无法正常工作
使用SwipeToRefresh刷新Fragment遇到的问题
XML布局代码
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/gradient_drawable" android:padding="10dp" xmlns:app="http://schemas.android.com/apk/res-auto" tools:context=".Fragment_1"> <androidx.swiperefreshlayout.widget.SwipeRefreshLayout android:id="@+id/swipe" android:layout_width="match_parent" android:layout_height="match_parent"> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent"> <ProgressBar android:id="@+id/progress" android:layout_width="76dp" android:layout_height="64dp" android:elevation="10dp" android:foregroundGravity="center" android:indeterminateTint="@color/black" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.84" /> <androidx.recyclerview.widget.RecyclerView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" android:padding="5dp"/> </androidx.constraintlayout.widget.ConstraintLayout> </androidx.swiperefreshlayout.widget.SwipeRefreshLayout> </FrameLayout>
Java代码(原代码)
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view=inflater.inflate(R.layout.fragment_1, container, false); newconfig= getResources().getConfiguration(); db=new DBHandler(getActivity()); swipeRefreshLayout=view.findViewById(R.id.swipe); recyclerView=view.findViewById(R.id.listview); progressBar=view.findViewById(R.id.progress); if(book.size()==0) { book = db.readCourses(); } progressBar.setVisibility(View.GONE); BookFragAdapter adapter = new BookFragAdapter(Fragment_land1.this,book); recyclerView.setLayoutManager(new LinearLayoutManager(getActivity(),RecyclerView.VERTICAL,false)); recyclerView.setAdapter(adapter); swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { this.onRefresh(); getFragmentManager().beginTransaction().detach(Fragment_land1.this).attach(Fragment_land1.this).commit(); swipeRefreshLayout.setRefreshing(false); } }); return view; }
问题描述
尝试刷新时,Fragment无法完成刷新,SwipeToRefresh的加载动画也不会自动停止,推测OnRefreshListener内的代码未执行。
问题原因及解决方案
核心问题
你在onRefresh()方法里调用了this.onRefresh();,这是无限递归调用,会导致方法一直循环自身,后面的detach/attach Fragment和setRefreshing(false)代码根本无法执行,自然会出现动画停不下来、Fragment不刷新的情况。
修复步骤
- 移除递归调用:删掉
this.onRefresh();这行代码。 - 优化刷新逻辑:不需要通过detach/attach Fragment来刷新,直接重新加载数据并更新RecyclerView即可,这种方式更高效且避免Fragment重建的开销。
修改后的OnRefreshListener代码示例
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { // 重新从数据库加载数据 book.clear(); book.addAll(db.readCourses()); // 通知适配器数据更新 recyclerView.getAdapter().notifyDataSetChanged(); // 停止刷新动画 swipeRefreshLayout.setRefreshing(false); } });
额外优化提示
如果数据库操作是耗时操作,建议放在子线程执行,避免阻塞主线程:
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { new Thread(new Runnable() { @Override public void run() { // 子线程加载数据 final List<Book> newBooks = db.readCourses(); // 回到主线程更新UI getActivity().runOnUiThread(new Runnable() { @Override public void run() { book.clear(); book.addAll(newBooks); recyclerView.getAdapter().notifyDataSetChanged(); swipeRefreshLayout.setRefreshing(false); } }); } }).start(); } });
内容的提问来源于stack exchange,提问作者Shakthi
相关产品推荐
相关产品推荐

