美文网首页
SwipeRefreshLayout-下拉刷新

SwipeRefreshLayout-下拉刷新

作者: 珞神 | 来源:发表于2017-10-10 14:13 被阅读0次

一、简介

  • 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();
}


  • 这种实现方式没有实现加载时的加载过程,用户感知不到!

相关文章

网友评论

      本文标题:SwipeRefreshLayout-下拉刷新

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