Swiperefreshlayout实现下拉加载刷新

1. Demo展示

image

2. Swiperefreshlayout介绍

  • 首先是依赖包
dependencies {
    implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
}
  • 官方文档描述

The SwipeRefreshLayout should be used whenever the user can refresh the contents of a view via a vertical swipe gesture. The activity that instantiates this view should add an OnRefreshListener to be notified whenever the swipe to refresh gesture is completed. The SwipeRefreshLayout will notify the listener each and every time the gesture is completed again; the listener is responsible for correctly determining when to actually initiate a refresh of its content. If the listener determines there should not be a refresh, it must call setRefreshing(false) to cancel any visual indication of a refresh. If an activity wishes to show just the progress animation, it should call setRefreshing(true). To disable the gesture and progress animation, call setEnabled(false) on the view.

This layout should be made the parent of the view that will be refreshed as a result of the gesture and can only support one direct child. This view will also be made the target of the gesture and will be forced to match both the width and the height supplied in this layout. The SwipeRefreshLayout does not provide accessibility events; instead, a menu item must be provided to allow refresh of the content wherever this gesture is used.

翻译版本:

当用户可以通过垂直滑动手势刷新视图内容时,就应该使用SwipeRefreshLayout。实例化此视图的活动应该添加一个OnRefreshListener,以便在完成刷新手势时得到通知。SwipeRefreshLayout会在每次手势再次完成时通知监听器;侦听器负责正确地确定何时真正开始刷新其内容。如果侦听器确定不应该进行刷新,则必须调用setRefreshing(false)来取消任何刷新的可视指示。如果一个活动希望只显示进度动画,它应该调用setRefreshing(true)。要禁用手势和进度动画,请在视图上调用setEnabled(false)。

这个布局应该成为视图的父视图,该视图将作为手势的结果刷新,并且只能支持一个直接子视图。该视图也将成为手势的目标,并将被迫匹配此布局中提供的宽度和高度。SwipeRefreshLayout不提供可访问事件;相反,必须提供一个菜单项,以允许在使用此手势的任何地方刷新内容。

  • 重点提取
    • 一般SwipeRefreshLayout用于垂直刷新视图
    • 在实例化视图活动也就是使用刷新功能时应该添加一个OnRefreshListener,以便在完成刷新手势时得到通知
    • 只能支持一个直接子视图,也就是SwipeRefreshLayout只能包裹一个子视图即ListView或者RecycleView等

3. 核心描述

  • isRefreshing()

    返回当前状态是不是刷新状态

  • setColorSchemeResources(int... colorResIds)

    设置下拉进度条的颜色,参数为可变参数int... colorResIds,参数是资源id也就是color里的资源,可以设置不同的颜色,每转一圈就显示一种颜色,按照给的参数顺序显示颜色。

  • setOnRefreshListener(SwipeRefreshLayout.OnRefreshListener listener)

    设置刷新监听,需要重写onRefresh()方法,一般从顶部下拉刷新时会调用此方法,在此方法设置刷新数据具体逻辑以及设置下拉进度条消失等一些工作

  • setRefreshing(boolean refreshing)

4. 代码使用和Demo描述

activity_main.xml

SwipeRefreshLayout里面只包含一个RecycleView,官方文档描述有说明

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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">

    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
        android:id="@+id/srl_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rv_main"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity

public class MainActivity extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener {

    private SwipeRefreshLayout mRefreshLayout;
    private RecyclerView       mRecyclerView;
    private List<Tag>          mTags = new ArrayList<>();
    private DemoAdapter        mAdapter;
    private int count = mTags.size();

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


    /**
     * 初始化视图View
     */
    public void initView() {
        mRefreshLayout = findViewById(R.id.srl_main);
        mRecyclerView = findViewById(R.id.rv_main);

        mAdapter = new DemoAdapter(mTags);

        // 设置layoutManager
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(layoutManager);
        mRecyclerView.setAdapter(mAdapter);
    }

    /**
     * 初始化数据,首先给出5个Tag数据
     */
    public void initData() {
        for (int i = 0; i < 5; i++) {
            Tag tag = new Tag(i + "", "name-" + i);
            mTags.add(tag);
        }

        count = mTags.size();
    }

    /**
     * 初始化事件
     */
    public void initEvent() {
        // 设置下拉监听
        mRefreshLayout.setOnRefreshListener(this);
        // 刷新渐变颜色
        mRefreshLayout.setColorSchemeResources(
                R.color.colorPrimary,
                R.color.colorPrimaryDark,
                R.color.colorAccent
        );

    }

    /**
     * 刷新方法
     */
    @Override
    public void onRefresh() {
        addData();
    }

    /**
     * 真正的刷新逻辑在这里,自定义的,根据情况自己写
     */
    private void addData() {
        // 延迟2s刷新
        mHandler.postDelayed(mRefresh, 2000);
    }

    private Handler mHandler = new Handler();

    private Runnable mRefresh = new Runnable() {
        @Override
        public void run() {
            mRefreshLayout.setRefreshing(false);

            int now = mTags.size()+5;
            for (; count < now; count++) {
                Tag tag = new Tag(count + "", "name-" + count);
                mTags.add(tag);
            }

            Log.d("tags",mTags.toString());
            Log.d("tags",mTags.size()+"");
            mAdapter.notifyDataSetChanged();
        }
    };
}

DemoAdapter

public class DemoAdapter extends RecyclerView.Adapter<DemoAdapter.ViewHolder> {
    private List<Tag> mTags;

    public DemoAdapter(List<Tag> tags) {
        mTags = tags;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new ViewHolder(
                LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.item_tag, parent, false));
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        holder.tvTagId.setText(mTags.get(position).getTagId());
        holder.tvTagName.setText(mTags.get(position).getTagName());
    }

    @Override
    public int getItemCount() {
        return mTags.size();
    }

    class ViewHolder extends RecyclerView.ViewHolder {
        TextView tvTagId;
        TextView tvTagName;

        private ViewHolder(View view) {
            super(view);
            tvTagId = view.findViewById(R.id.tv_tagid);
            tvTagName = view.findViewById(R.id.tv_tagName);
        }
    }
}

item_tag.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="5dp"
    android:layout_marginBottom="5dp"
    android:background="@color/colorAccent"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/tv_tagid"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="center"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/tv_tagName"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="center"
        android:textSize="20sp" />

</LinearLayout>

Tag实体类

public class Tag {
    private String tagId;
    private String tagName;

    public Tag(String tagId, String tagName) {
        this.tagId = tagId;
        this.tagName = tagName;
    }

    public String getTagId() {
        return tagId;
    }

    public void setTagId(String tagId) {
        this.tagId = tagId;
    }

    public String getTagName() {
        return tagName;
    }

    public void setTagName(String tagName) {
        this.tagName = tagName;
    }

    @Override
    public String toString() {
        return "Tag{" +
                "tagId='" + tagId + '\'' +
                ", tagName='" + tagName + '\'' +
                '}';
    }
}

GitHub

Demo示例的代码在这里哦

SwipeRefreshLayoutDemo

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

推荐阅读更多精彩内容