SwipeRefreshLayout-下拉刷新

一、简介

  • SwipeRefreshLayout 是 Google 官方提供的一个下拉刷新的控件。

  • 注意包的位置:android.support.v4.widget.SwipeRefreshLayout

二、使用

  • 用法很简单,将需要下拉刷新功能的控件放在 SwipeRefreshLayout 中,注意,SwipeRefreshLayout 只能有一个子控件。
2.1 xml 布局文件如下所示:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:fresco="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <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="wrap_content"
                android:background="@color/colorPrimaryDark"
                android:fitsSystemWindows="true"
                android:minHeight="?attr/actionBarSize"
                android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
                app:layout_scrollFlags="scroll|enterAlways|snap"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light">

                <!--自定义控件-->
                <TextView
                    android:id="@+id/toolbar_title"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerInParent="true"
                    android:layout_gravity="center"
                    android:gravity="center"
                    android:text="FloatingActionButton"
                    android:textSize="20dp"
                    android:textStyle="bold" />

            </android.support.v7.widget.Toolbar>
        </android.support.design.widget.AppBarLayout>
        <!-- app:layout_behavior="@string/appbar_scrolling_view_behavior" 指定一个布局行为-->
        <!--下拉刷新控件 SwipeRefreshLayout-->
        <android.support.v4.widget.SwipeRefreshLayout
            android:id="@+id/swiperefreshlayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">

            <!--RecyclerView-->
            <android.support.v7.widget.RecyclerView
                android:id="@+id/recycler_view"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_below="@id/toolbar"></android.support.v7.widget.RecyclerView>
        </android.support.v4.widget.SwipeRefreshLayout>
        <!--FloatingActionButton-->

        <android.support.design.widget.FloatingActionButton
            android:id="@+id/floating"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|end"
            android:layout_margin="16dp"
            android:src="@drawable/floating_icon"
            app:fabSize="normal"
            app:pressedTranslationZ="10dp"
            app:rippleColor="@color/colorAccent"

            />

    </android.support.design.widget.CoordinatorLayout>


</RelativeLayout>

  • 可以看到,SwipeRefreshLayout 中包裹了一个 RecyclerView ,也就是说,RecyclerView 是需要下拉刷新的控件。
2.2 代码中还有一些设置
public class MyRecyclerViewActivity extends AppCompatActivity {

    @BindView(R.id.floating)
    FloatingActionButton floating;
    @BindView(R.id.toolbar_title)
    TextView toolbarTitle;
    @BindView(R.id.toolbar)
    Toolbar toolbar;
    @BindView(R.id.recycler_view)
    RecyclerView recyclerView;
    @BindView(R.id.swiperefreshlayout)
    SwipeRefreshLayout swiperefreshlayout;
    private Snackbar snackbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recyclerview_appbarlayout);
        ButterKnife.bind(this);

        //设置透明状态栏
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            WindowManager.LayoutParams localLayoutParams = getWindow().getAttributes();
            localLayoutParams.flags = (WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | localLayoutParams.flags);
        }
        toolbar.setTitle("");
        setSupportActionBar(toolbar);
        toolbar.setNavigationIcon(R.drawable.setting);

        initRecyclerViewData();
        initRcyclerView();
        
        initSwipeRefreshLayout();

    }

    /**
     * 初始化下拉刷新控件,SwipeRefreshLayout
     */
    private void initSwipeRefreshLayout() {
        //设置刷新进度条的颜色变化,最多可以设置 4 种,加载的颜色是循环播放的。
        swiperefreshlayout.setColorSchemeResources(R.color.colorAccent);
        //设置手指在屏幕上下拉多少会触发下拉刷新
        swiperefreshlayout.setDistanceToTriggerSync(300);
        //设置下拉刷新的圆圈背景颜色
        swiperefreshlayout.setProgressBackgroundColorSchemeColor(Color.WHITE);
        //设置下拉刷新的圆圈大小
        swiperefreshlayout.setSize(SwipeRefreshLayout.DEFAULT);
        // 设置刷新时候的监听事件
        swiperefreshlayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                
                //执行刷新之后的操作,一般都是联网请求数据
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                initData();
                                myRecyclerAdapter.notifyDataSetChanged();
                                //停止刷新
                                swiperefreshlayout.setRefreshing(false);
                            }

                            private void initData() {

                                listData.add("我是刷新时候添加的数据");
                                listData.add("我是刷新时候添加的数据");
                                listData.add("我是刷新时候添加的数据");
                                listData.add("我是刷新时候添加的数据");
                            }
                        });
                    }
                }).start();
                
                
                
            }
        });
2.3 运行效果如下:
image

三、添加上拉加载更多

思路: 利用 RecyclerView 的 addOnScrollListener 方法,自己动手实现滑动监听,当屏幕可见的最后一条条目显示出来的时候,实现加载更多的逻辑。

3.1 Activity 中使用时的代码:
  //上拉加载更多
      recyclerView.addOnScrollListener(new MyRecyclerViewOnScrollListener(linearLayoutManager) {
          @Override
          public void loadMoreDate() {
              listData.add("我是上拉加载时候添加的数据");
              listData.add("我是上拉加载时候添加的数据");
              myRecyclerAdapter.notifyDataSetChanged();
          }
      });
3.2 MyRecyclerViewOnScrollListener 中的代码:

/**
 * RecyclerView 滑动监听,目的:实现上拉加载更过多
 */

public abstract class MyRecyclerViewOnScrollListener extends RecyclerView.OnScrollListener {

    private LinearLayoutManager linearLayoutManager;
    //屏幕上可见的 item 数量
    private int visibleItemCount;
    //已经加载出来的 item 数量
    private int totalItemCount;
    //屏幕上可见的第一个 item
    private int firstVisibleItem;
    //是否正在上拉加载数据中
    private boolean isLoadingMore = false;
    //记录之前的数据总数
    private int agoneTotle;

    public MyRecyclerViewOnScrollListener(LinearLayoutManager linearLayoutManager) {
        this.linearLayoutManager = linearLayoutManager;

    }

    /**
     * 滑动状态改变
     *
     * @param recyclerView 当前滚动的 RecyclerView
     * @param newState     当前滚动的状态,有三个值
     *                     public static final int SCROLL_STATE_IDLE = 0;静止没滚动
     *                     public static final int SCROLL_STATE_DRAGGING = 1;用户正在用手指滚动
     *                     public static final int SCROLL_STATE_SETTLING = 2;自动滚动
     */
    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
    }

    /**
     * 正在滑动
     *
     * @param recyclerView 当前滚动的 RecyclerView
     * @param dx           水平滚动距离
     * @param dy           垂直滚动距离
     *                     dx > 0 时为手指向左滚动,列表滚动显示右面的内容
     *                     dx < 0 时为手指向右滚动,列表滚动显示左面的内容
     *                     dy > 0 时为手指向上滚动,列表滚动显示下面的内容
     *                     dy < 0 时为手指向下滚动,列表滚动显示上面的内容
     */
    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        //向下滑动
        if (dy > 0) {
            visibleItemCount = linearLayoutManager.getChildCount();
            totalItemCount = linearLayoutManager.getItemCount();
            firstVisibleItem = linearLayoutManager.findFirstVisibleItemPosition();
        }
        //如果正在加载中
        if(isLoadingMore){
            //说明加载结束
            if(totalItemCount > agoneTotle){

                isLoadingMore = false;
                agoneTotle = totalItemCount;
            }
        }
        //如果没有正在加载中,并且,当前屏幕上可见 item 的总数 + 屏幕上可见第一条 item 大于等于 目前加载出来的数据总数
        if (!isLoadingMore && (visibleItemCount + firstVisibleItem) >= totalItemCount) {
            isLoadingMore = true;
            //加载更多数据,设置一个抽象方法来实现具体的加载逻辑
            loadMoreDate();
        }
    }
    
    public abstract void loadMoreDate();
}


  • 这种实现方式没有实现加载时的加载过程,用户感知不到!
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容