第十六个项目——使用SwipeRefreshLayout实现下拉刷新

实验目的

  • 掌握SwipeRefreshLayout布局控件使用方式;

实验要求

  • 掌握SwipeRefreshLayout进行刷新加载数据的方法;

实验内容

第七个项目ListView中的数据在MainActivity初始化时从arrays.xml文件中进行读取,其数量是固定的。实际项目开发中,通常需要通过下拉页面进行数据的刷新加载。本实验中通过使用SwipeRefreshLayout实现页面的下拉刷新,为了简便起见,当用户下拉刷新App页面时,从arrays.xml随机生成一条新闻加入ListView的顶部,项目的最终运行效果如图1 SwipeRefreshLayout实现下拉刷新所示。

图1-a. 下拉刷新
图1-b. 释放下拉
图1-c. 再次下拉刷新
图1-d. 释放下拉

步骤一,打开第七个项目或第十五个项目

打开第七个项目第十五个项目,在该项目基础上完成本次实验。

步骤二,修改activity_main.xml布局文件

打开activity_main.xml文件,需要加入SwipeRefreshLayout控件作为ListView控件的父容器,具体代码如下所示。

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/swipe"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_margin="8dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent">
        <ListView
            android:id="@+id/lv_news_list"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:scrollbars="none"
            android:divider="@android:color/transparent"
            android:dividerHeight="8dp"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            />
    </android.support.v4.widget.SwipeRefreshLayout>
</android.support.constraint.ConstraintLayout>

步骤二,修改MainActivity.java文件

1. 在MainActivity类中定义SwipeRefreshLayout控件对象

MainActivity类中定义私有SwipeRefreshLayout控件对象,并在onCreate()方法中进行控件对象绑定操作。

2. 设置SwipeRefreshLayout控件下拉刷新事件侦听器

响应SwipeRefreshLayout控件的下拉刷新需要设置该控件的OnRefreshListener事件侦听器,在onRefresh()方法中调用了MainActivity类定义的私有方法,用于刷新数据。

上述两步的代码如下所示。

public class MainActivity extends AppCompatActivity {
    ...
    private List<News> newsList = new ArrayList<>();
    private NewsAdapter newsAdapter = null;
    private ListView lvNewsList;

    private SwipeRefreshLayout swipe;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initData();

        NewsAdapter newsAdapter = new NewsAdapter(MainActivity.this,
                R.layout.list_item, newsList);

        ListView lvNewsList = findViewById(R.id.lv_news_list);
        lvNewsList.setAdapter(newsAdapter);

        swipe = findViewById(R.id.swipe);  

        ...

        swipe.setOnRefreshListener(
            new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                refreshData();
            }
        });
    }
    ...
}

3. 定义refreshData()私有方法刷新数据

刷新数据主要通过实例化一个News新闻对象,该对象数据仍然从arrays.xml数组资源文件中得到,但是采用了Random对象随机产生范围从 0~19 的下标,从而模拟生成新的新闻对象。

通过NewsAdapter.insert(News object, int index)方法将随机生成的News新闻对象插入数据源的头部(index为0)。当NewsAdapter适配器中的数据发生变化时,需要调用NewsAdapter.notifyDataSetChanged()方法通知与适配器绑定的ListView列表UI控件刷新页面。

最后调用SwipeRefreshLayout.setRefreshing(false)方法,取消刷新动作并隐藏SwipeRefreshLayout控件。

public class MainActivity extends AppCompatActivity {
    ...
    private void refreshData() {
        Random random = new Random();
        int index = random.nextInt(19);

        News news = new News();

        news.setTitle(titles[index]);
        news.setAuthor(authors[index]);
        news.setContent(contents[index]);
        news.setImageId(images.getResourceId(index, -1));

        newsAdapter.insert(news, 0);
        newsAdapter.notifyDataSetChanged();
        swipe.setRefreshing(false);
    }
}

步骤三,编译项目并部署APK运行

完成上述步骤后,编译项目并将其部署至虚拟机或物理机上,App运行后,在新闻列表页中下拉刷新观察新闻列表是否响应刷新动作在列表顶部新增一条新闻,App运行结果应与图1 SwipeRefreshLayout实现下拉刷新相同。

实验小结

通过本次实验,你应该掌握了如下知识内容:

  • 使用SwipeRefreshLayout响应下拉刷新;

  • 使用Adapter.notifyDataSetChanged()等方法进行数据变更;

Last updated

Was this helpful?