美文网首页Android技术知识程序员Android开发
Material Design 实战 之第五弹 —— 下拉刷新(

Material Design 实战 之第五弹 —— 下拉刷新(

作者: 凌川江雪 | 来源:发表于2018-10-02 21:01 被阅读23次

    本模块共有六篇文章,参考郭神的《第一行代码》,对Material Design的学习做一个详细的笔记,大家可以一起交流一下:






    引子:


    文章提要与总结


    SwipeRefreshLayout
    
        1.SwipeRefreshLayout即是实现下拉刷新功能的核心类,它由support-v4库提供的;
    
        2.把想要实现下拉刷新功能的控件放置到SwipeRefreshLayout里边,即可迅速让这个控件支持下拉刷新了;
    
        3.接下来在对应的java代码中处理具体的刷新逻辑:
            3.1 实例化SwipeRefreshLayout;
            3.2 调用setcolorSchemeResources()方法来设置下拉刷新进度条的颜色;
            3.3 调用setonRefreshListener()方法设置一个下拉刷新的监听器, 
                传入一个SwipeRefreshLayout.OnRefreshListener()并重写onRefresh()来处理具体的刷新逻辑;
    
            3.4 刷新逻辑使用中可以使用如下多线程结构:
             new Thread(new Runnable() {
                @Override
                public void run() {
                    try{
    
                    }catch (InterruptedException e){
                        e.printStackTrace();
                    }
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
    
                        }
                    });
                }
            }).start();
    
        其中try中书写耗时操作,然后在 runOnUiThread() 中的 run() 中获取到数据,
        并adapter.notifyDataSetChanged()调用刷新数据;
        最后调用swipeRefreshLayout的setRefreshing()并传入false,表示刷新事件结束同时隐藏刷新进度条;
    



    正文


    SwipeRefreshLayout

    SwipeRefreshLayout即是实现下拉刷新功能的核心类,它由support-v4库提供的。

    把想要实现下拉刷新功能的控件放置到SwipeRefreshLayout里边,即可迅速让这个控件支持下拉刷新了。
    而在这里的实战项目(MaterialTest)中,应该支持下拉刷新功能的控件是RecyclerView。

    下面直接开始使用它。修改activity-main.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v4.widget.DrawerLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <android.support.design.widget.CoordinatorLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
           <android.support.design.widget.AppBarLayout
               android:layout_width="match_parent"
               android:layout_height="wrap_content">
               <android.support.v7.widget.Toolbar
                   android:id="@+id/toolbar"
                   android:layout_width="match_parent"
                   android:layout_height="?attr/actionBarSize"
                   android:background="?attr/colorPrimary"
                   android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
                   app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                   app:layout_scrollFlags="scroll|enterAlways|snap"/>
           </android.support.design.widget.AppBarLayout>
    
            <android.support.v4.widget.SwipeRefreshLayout
                android:id="@+id/swipe_refresh"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:layout_behavior = "@string/appbar_scrolling_view_behavior">
                <android.support.v7.widget.RecyclerView
                    android:id="@+id/recycler_view"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent" />
            </android.support.v4.widget.SwipeRefreshLayout>
    
            <android.support.design.widget.FloatingActionButton
                android:id="@+id/fab"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="bottom|end"
                android:layout_margin="16dp"
                android:src="@drawable/ic_done"
                app:elevation="8dp"/>
        </android.support.design.widget.CoordinatorLayout>
    
        <android.support.design.widget.NavigationView
            android:id="@+id/nav_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            app:menu="@menu/nav_menu"
            app:headerLayout="@layout/nav_header">
    
        </android.support.design.widget.NavigationView>
    
    </android.support.v4.widget.DrawerLayout>
    

    这里在RecyclerView的外面再嵌套一层SwipeRefreshLayout,让RecyclerView实现下拉刷新功能。

    另注意,
    由于RecyclerView现在变成了Swipe-RefreshLayout的子控件,
    因此之前使用app:layout_behavxor声明的布局行为现在也要移到SwipeRefreshLayout中才行。

    当然,虽RecyclerView已经支持下拉刷新功能,但还要在代码中处理具体的刷新逻辑才行。
    下面修改MainActivity:

    //下拉刷新
        private SwipeRefreshLayout swipeRefresh;
    ------------------------------------
    
    
     //下拉刷新逻辑处理
            swipeRefresh = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh);
            swipeRefresh.setColorSchemeResources(R.color.colorPrimary);
            swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.
                    OnRefreshListener(){
                @Override
                public void onRefresh() {
                    refreshFruits();
                }
            });
    ------------------------------------
    
     private void refreshFruits(){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try{
                        Thread.sleep(2000);
                    }catch (InterruptedException e){
                        e.printStackTrace();
                    }
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            initFruits();
                            adapter.notifyDataSetChanged();
                            swipeRefresh.setRefreshing(false);
                        }
                    });
                }
            }).start();
        }
    
    

    这里,
    首先实例化SwipeRefreshLayout,
    然后调用setcolorSchemeResources()方法来设置下拉刷新进度条的颜色,这里使用主题中的colorPrimary作为进度条的颜色。
    接着调用setonRefreshListener()方法设置一个下拉刷新的监听器,当触发了下拉刷新操作的时候就会回调这个监听器的onRefresh()方法,在这个方法中处理具体的刷新逻辑。(这里可以类比setOnClickListener理解)

    通常onRefresh()方法中应该是去网络上请求最新的数据,然后再将这些数据展示出来。
    这里就不和网络交互了,简单地写一个refreshFruits()方法并调用它进行本地刷新操作。

    refreshFruits()方法中先是开启了一个线程,然后将线程沉睡两秒钟,模拟刷新的等待过程。
    因为本地刷新操作速度非常快,如果不将线程沉睡的话,刷新会即刻结束而看不到刷新的过程。
    沉睡结束后使用run0nUiThread()方法将线程切换回主线程,
    调用initFruits()方法重新生成数据,
    接着调用FruitAdapter的notifyDataSetChanged()通知数据发生了变化并刷新adapter里面的数据,
    最后调用swipeRefreshLayout的setRefreshing()并传入false,表示刷新事件结束同时隐藏刷新进度条。

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

    刷新中
    刷新后

    下拉刷新进度条会停留两秒钟,随后自动消失,水果列表也会更新了。

    相关文章

      网友评论

        本文标题:Material Design 实战 之第五弹 —— 下拉刷新(

        本文链接:https://www.haomeiwen.com/subject/vnzooftx.html