12.6--下拉刷新

下拉刷新这种功能早就不是什么新鲜的东西了,几乎所有的应用里都会有这个功能。不过市面上现有的下拉刷新功能在风格上都各不相同,并且和 Material Design 还有些格格不人的感党。因此,Google为了让 Android 的下拉刷新风格能有一个统一的标准,于是在 Material Design 中制定了一个官方的设计规范。当然,我们并不需要去深入了解这个规范到底是什么样的,因为Google早就提供好了现成的控件,我们只需要在项目中直接使用就可以了。

SwipeRefreshLayout 就是用于实现下拉刷新功能的核心类,它是由 AndroidX库提供的。我们把想要实现下拉刷新功能的控件放置到 SwipeRefreshLayout 中,就可以迅速让这个控件支持下拉刷新。那么在 MaterialTest 项目中,应该支持下拉刷新功能的控件自然就是 RecyclerView 了。

由于 SwipeRefreshLayout 的用法也比较简单,下面我们就直接开始使用了。修改activity_main.xml 中的代码,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawerLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".MainActivity">

    <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"
                />

        </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
            }
        }
    }

    private fun initFruits(){
        fruitList.clear()
        repeat(50){
            val index = (0 until fruits.size).random()
            fruitList.add(fruits[index])
        }
    }
    ...

}

这段代码应该还是比较好理解的,首先调用SwipeRefreshLayout 的 setColorSchemeResources() 方法来设置下拉刷新进度条的颜色,这里我们就使用主题中的 colorPrimary 作为进度条的颜色了。接着调用 setOnRefreshListener() 方法来设置一个下拉刷新的监听器,当触发了下拉刷新操作的时候就会回调这个监听器的 onRefresh() 方法,然后我们在这里去处理具体的刷新逻辑就可以了。

通常情况下,onRefresh() 方法中应该是去网络上请求最新的数据,然后再将这些数据展示出来。这里简单起见,我们就不和网络进行交互了,而是调用一个 refreshFruits() 方法进行本地刷新操作。refreshFruits() 方法中先是开启了一个线程,然后将线程沉睡两秒钟。之所以这么做,是因为本地刷新操作速度非常快,如果不将线程沉睡的话,刷新立刻就结束了,从而看不到刷新的过程。沉睡结東之后,这里使用了 runOnUiThread()方法将线程切换回主线程,然后调用 initFruits() 方法重新生成数据,接着再调用 FruitAdapter 的 notifyDataSetChanged() 方法通知数据发生了变化,最后调用 SwipeRefreshLayout 的 setRefreshing() 方法并传人 false,用于表示刷新事件结束,并隐藏刷新进度条。

现在可以重新运行一下程序了,在屏幕的主界面向下拖动,会有一个下拉刷新的进度条出现松手后就会自动进行刷新了,效果如图所示。

下拉刷新的进度条只会停留两秒钟,之后就会自动消失,界面上的水果数据也会随之更新。

这样我们就把下拉刷新的功能也成功实现了,并且这就是 Material Design 中规定的最标准的下拉刷新效果,还有什么会比这个更好看呢?目前我们的项目中已经应用了众多 Material Design 的效果,Material 库中的常用控件也学了大半了。不过本章的学习之旅还没有结束,在最后的尾声部分,我们再来实现一个非常震撼的 Material Design 效果—可折叠式标题栏。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值