下拉刷新的核心类: SwipeRefreshLayout
下拉刷新这种功能并不是什么新鲜的东西,所有的应用里都会有这个功能
把想要实现下拉刷新功能的控件放置到SwipeRefreshLayout中,就可以迅速让这个控件支持下拉刷新
使用SwipeRefreshLayout之前首先需要在app/build.gradle文件中dependencies的闭包添加如下依赖:
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0
修改activity_main.xml中的代码
<androidx.drawerlayout.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
...
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipeRefresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
...
</androidx.coordinatorlayout.widget.CoordinatorLayout>
...
</androidx.drawerlayout.widget.DrawerLayout>
这里在RecyclerView的外面又嵌套了一层SwipeRefreshLayout,这样RecyclerView就自动拥有下拉刷新功能了
由于RecyclerView现在变成了SwipeRefreshLayout的子控件,因此之前使用app:layout_behavior声明的布局行为现在也要移到SwipeRefreshLayout中才行
不过这还没有结束,虽然RecyclerView已经支持下拉刷新功能了,但是还要在代码中处理具体的刷新逻辑才行。修改MainActivity中的代码,如下所示:
class MainActivity : AppCompatActivity() {
...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
...
swipeRefresh.setColorSchemeResources(R.color.colorPrimary)
swipeRefresh.setOnRefreshListener {
refreshFruits(adapter)
}
}
private fun refreshFruits(adapter: FruitAdapter) {
thread {
Thread.sleep(2000)
runOnUiThread {
initFruits()
adapter.notifyDataSetChanged()
swipeRefresh.isRefreshing = false
}
}
}
...
}
首先调用SwipeRefreshLayout的setColorSchemeResources()方法来设置下拉刷新进度条的颜色,这里就使用主题中的colorPrimary作为进度条的颜色了
接着调用setOnRefreshListener()方法来设置一个下拉刷新的监听器,当用户进行了下拉刷新操作时,就会回调到Lambda表达式当中,然后在这里去处理具体的刷新逻辑就可以了
这里简单起见,就不和网络进行交互了,而是调用一个refreshFruits()方法进行本地刷新操作>refreshFruits()方法中先是开启了一个线程,然后将线程沉睡两秒钟。之所以这么做,是因为本地刷新操作速度非常快,如果不将线程沉睡的话,刷新立刻就结束了,从而看不到刷新的过程
沉睡结束之后,这里使用了runOnUiThread()方法将线程切换回主线程,然后调用initFruits()方法重新生成数据,接着再调用FruitAdapter的notifyDataSetChanged()方法通知数据发生了变化,最后调用SwipeRefreshLayout的setRefreshing()方法并传入false,表示刷新事件结束,并隐藏刷新进度条
运行程序,在屏幕的主界面向下拖动,会有一个下拉刷新的进度条出现,松手后就会自动进行刷新了
下拉刷新的进度条只会停留两秒钟,之后就会自动消失,界面上的水果数据也会随之更新