热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

android的SwipeRefreshLayout+RecycleView实现上拉加载下拉刷新

android的SwipeRefreshLayout+RecycleView实现上拉加载下拉刷新,Go语言社区,Golang程序员人脉社

介绍

本文主要实现的是上拉加载更多功能,下拉刷新使用的是Google官方的SwipeRefreshLayout控件,但是却没有实现上拉加载。我们一般用到上拉加载功能都是在列表显示中,所以本文用SwipeRefreshLayout配合RecycleView实现上拉加载和下拉刷新功能。

实现

下拉刷新我们用SwipeRefreshLayout原生的能力即可,主要是如何实现上拉加载呢?简单的实现思路如下:通过监听RecycleView的上拉操作,在其滚动监听状态中判断当前显示的item是不是最后一个item从而决定是否调用加载更多操作。
首先看主布局:




    
        
        
        
    


在RecyclerView外层套一个SwipeRefreshLayout即可
接着item的布局



    
    
        
    


footer的布局




    
        

        
    

    


下面就是主要的部分,adapter的实现了,代码里的注释都比较清晰了。

public class RefreshLoadRecycleAdapter extends RecyclerView.Adapter{

    private ArrayList mDatas;

    private final int ITEM_TYPE =0; //item布局类型
    private final int FOOTER_TYPPE = 1; //footer布局类型
    public static final int LOADING = 0; //加载中
    public static final int LOAD_FINISH = 1; //加载完成
    public static final int LOAD_END =2;  //加到底

    private int loadState = LOAD_FINISH;

    public RefreshLoadRecycleAdapter( ArrayList datas){
        mDatas = datas;
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if(viewType == FOOTER_TYPPE){
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.footer_layout,parent,false);
            return new FooterViewHolder(view);
        }else if(viewType == ITEM_TYPE){
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout,parent,false);
            return new ItemViewHolder(view);
        }
        return null;
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        if(holder instanceof ItemViewHolder){
            ItemViewHolder itemViewHolder = (ItemViewHolder)holder;
            itemViewHolder.tvContent.setText(mDatas.get(position));
        }else if(holder instanceof FooterViewHolder){
            FooterViewHolder footerViewHolder = (FooterViewHolder)holder;
            if(loadState == LOADING){
                footerViewHolder.mProgressBar.setVisibility(View.VISIBLE);
                footerViewHolder.tvMsg.setVisibility(View.VISIBLE);
                footerViewHolder.tvBottom.setVisibility(View.GONE);
            }else if(loadState == LOAD_FINISH){
                footerViewHolder.mProgressBar.setVisibility(View.INVISIBLE);
                footerViewHolder.tvMsg.setVisibility(View.INVISIBLE);
                footerViewHolder.tvBottom.setVisibility(View.GONE);
            }else if(loadState == LOAD_END){
                footerViewHolder.mProgressBar.setVisibility(View.GONE);
                footerViewHolder.tvMsg.setVisibility(View.GONE);
                footerViewHolder.tvBottom.setVisibility(View.VISIBLE);
            }
        }
    }

    @Override
    public int getItemCount() {
        return mDatas.size() + 1;  //加一个footer布局
    }

    @Override
    public int getItemViewType(int positon){
        if(positon + 1 == getItemCount()){  //最后一个为footer布局
            return FOOTER_TYPPE;
        }
        return ITEM_TYPE;
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
        //适配gridiew 的情况
        if (manager instanceof GridLayoutManager) {
            final GridLayoutManager gridManager = ((GridLayoutManager) manager);
            gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    // 如果当前是footer的位置,那么该item占据n个单元格,正常情况下占据1个单元格
                    return getItemViewType(position) == FOOTER_TYPPE ? gridManager.getSpanCount() : 1;
                }
            });
        }
    }

    //添加刷新数据
    public void AddHeaderItem(ArrayList items){
        mDatas.addAll(0,items);
        notifyDataSetChanged();
    }

    //添加加载数据
    public void AddFooterItem(ArrayList items){
        mDatas.addAll(items);
        notifyDataSetChanged();
    }

    /**
     * 设置加载状态
     * @param loadState
     */
    public void setLoadState(int loadState) {
        this.loadState = loadState;
        notifyDataSetChanged();
    }

    //item 布局holder
    static class ItemViewHolder extends RecyclerView.ViewHolder{

        TextView tvContent;

        public ItemViewHolder(View itemView) {
            super(itemView);
            tvCOntent= itemView.findViewById(R.id.tvContent);
        }
    }
    //footer 布局holder
    static class FooterViewHolder extends RecyclerView.ViewHolder{

        ProgressBar mProgressBar;
        TextView tvMsg;
        TextView tvBottom;

        public FooterViewHolder(View itemView) {
            super(itemView);
            mProgressBar = itemView.findViewById(R.id.progressBar);
            tvMsg = itemView.findViewById(R.id.tvMsg);
            tvBottom = itemView.findViewById(R.id.tvBottom);
        }
    }
}

接着要实现RecycleView的滑动监听,判断滑动状态实现上拉刷新.这里用抽象类继承 RecyclerView.OnScrollListener来实现

public abstract class RecycleOnscrollListener extends RecyclerView.OnScrollListener{
    //用来标记是否正在向上滑动
    private boolean isSlidingUp = false;

    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);

        LinearLayoutManager manager = (LinearLayoutManager) recyclerView.getLayoutManager();
        // 当不滑动时
        if (newState == RecyclerView.SCROLL_STATE_IDLE) {
            //获取最后一个完全显示的itemPosition
            int lastItemPosition = manager.findLastCompletelyVisibleItemPosition();
            int itemCount = manager.getItemCount();

            // 判断是否滑动到了最后一个item,并且是向上滑动
            if (lastItemPosition == (itemCount - 1) && isSlidingUp) {
                //加载更多
                onLoadMore();
            }
        }
    }

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        // 大于0表示正在向上滑动,小于等于0表示停止或向下滑动
        isSlidingUp = dy > 0;
    }

    /**
     * 加载更多回调
     */
    public abstract void onLoadMore();

使用

前期的实现都完成了,下面看怎么使用.其实主要就是实现两个监听,下拉刷新( mRefreshLayout.setOnRefreshListener)和上拉( recyclerView.addOnScrollListener)

private SwipeRefreshLayout mRefreshLayout;
    private RecyclerView recyclerView;
    private RefreshLoadRecycleAdapter mRecycleAdapter;
    private ArrayList dataList = new ArrayList<>();

    private int page =  0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mRefreshLayout = findViewById(R.id.refreshLayout);
        recyclerView = findViewById(R.id.recyclerView);

        //进度条圈圈颜色
        mRefreshLayout.setColorSchemeColors(Color.RED,Color.BLUE,Color.GREEN);
       // mRefreshLayout.setColorSchemeResources(R.color.colorAccent);

        init();
    }

    private void init(){
        page = 0;
        getData(page);
        mRecycleAdapter = new RefreshLoadRecycleAdapter(dataList);
        recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
        recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
        //自定义分割线
       // recyclerView.addItemDecoration(new RecycleViewDivider(this, RecycleViewDivider.LIST_VERTICAL));
        recyclerView.setAdapter(mRecycleAdapter);

        initListener();

    }

    private void initListener(){
        //上拉加载
        recyclerView.addOnScrollListener(new RecycleOnscrollListener(){

            @Override
            public void onLoadMore() {
                mRecycleAdapter.setLoadState(RefreshLoadRecycleAdapter.LOADING);

                if (dataList.size() <= 60) {
                    // 模拟获取网络数据,延时3s
                    new Timer().schedule(new TimerTask() {
                        @Override
                        public void run() {
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    page++;
                                    getData(page);
                                    mRecycleAdapter.setLoadState(mRecycleAdapter.LOAD_FINISH);
                                }
                            });
                        }
                    }, 3000);
                } else {
                    // 显示加载到底的提示
                    page = 0;
                    mRecycleAdapter.setLoadState(mRecycleAdapter.LOAD_END);
                }
            }
        });

        //下拉刷新
        mRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        ArrayList headDatas = new ArrayList();
                        for (int i = 0; i <20 ; i++) {

                            headDatas.add("Heard Item "+i);
                        }
                        mRecycleAdapter.AddHeaderItem(headDatas);

                        //刷新完成
                        mRefreshLayout.setRefreshing(false);   //一定记得set,不然刷新动画一直在
                        Toast.makeText(MainActivity.this, "更新了 "+headDatas.size()+" 条目数据", Toast.LENGTH_SHORT).show();
                    }

                }, 3000);
            }
        });
    }
    private void getData(int page){
        int ind = 20 * page;
        ArrayList datas = new ArrayList<>();
        for (int i = ind; i <20 + ind; i++) {
            datas.add("item " + i);
        }
        if(page ==0) {
            dataList.addAll(datas);
        }else {
            mRecycleAdapter.AddFooterItem(datas);
        }
    }

效果图:
下拉刷新
在这里插入图片描述
上拉加载
在这里插入图片描述

参考https://www.jianshu.com/p/b502c5b59998
另外github有大神实现了一个比较多功能的RecyclerView侧滑菜单,Item拖拽,滑动删除Item,自动加载更多等的开源项目,有兴趣可以看看https://github.com/yanzhenjie/SwipeRecyclerView


推荐阅读
  • <!DOCTYPEhtml><html><head><metacharsetUTF-8><meta ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • ASP.NET2.0数据教程之十四:使用FormView的模板
    本文介绍了在ASP.NET 2.0中使用FormView控件来实现自定义的显示外观,与GridView和DetailsView不同,FormView使用模板来呈现,可以实现不规则的外观呈现。同时还介绍了TemplateField的用法和FormView与DetailsView的区别。 ... [详细]
  • 带添加按钮的GridView,item的删除事件
    先上图片效果;gridView无数据时显示添加按钮,有数据时,第一格显示添加按钮,后面显示数据:布局文件:addr_manage.xml<?xmlve ... [详细]
  • 本文总结了在编写JS代码时,不同浏览器间的兼容性差异,并提供了相应的解决方法。其中包括阻止默认事件的代码示例和猎取兄弟节点的函数。这些方法可以帮助开发者在不同浏览器上实现一致的功能。 ... [详细]
  • Tkinter Frame容器grid布局并使用Scrollbar滚动原理
    本文介绍了如何使用Tkinter实现Frame容器的grid布局,并通过Scrollbar实现滚动效果。通过将Canvas作为父容器,使用滚动Canvas来滚动Frame,实现了在Frame中添加多个按钮,并通过Scrollbar进行滚动。同时,还介绍了更新Frame大小和绑定滚动按钮的方法,以及配置Scrollbar的相关参数。 ... [详细]
  • Highcharts翻译系列之二十:曲线图例子(二)
    Highcharts翻译系列之二十:曲线图例子(二)代码 ... [详细]
  • Android程序员面试宝典自定义控件一分钟实现贴纸功能一分钟实现TextView高亮一分钟实现新手引导页一分钟实现ViewPager卡片一分钟实现加载对话框一分钟实现轮播图一分钟 ... [详细]
  • 【clientX,offsetX,screenX】  【scrollWidth,clientWidth,offsetWidth】的区别
    一、深刻认识clientX,offsetX,screenX概念(来源于网络):clientX设置或获取鼠标指针 ... [详细]
  • 百度地图   绘制东莞东城地图示例
    先上图:index.html ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • 本文介绍了Python字典视图对象的示例和用法。通过对示例代码的解释,展示了字典视图对象的基本操作和特点。字典视图对象可以通过迭代或转换为列表来获取字典的键或值。同时,字典视图对象也是动态的,可以反映字典的变化。通过学习字典视图对象的用法,可以更好地理解和处理字典数据。 ... [详细]
  •  项目地址https:github.comffmydreamWiCar界面做的很难看,美工方面实在不在行。重点是按钮触摸事件的处理,这里搬了RepeatListener项目代码,例 ... [详细]
  • 如何用Matlab快速画出带有3D渲染效果的复杂曲面
    简要地介绍了一下如何用Matlab快速画出带有3D渲染效果的复杂曲面图,包括三维曲面绘制、光线、材质、着色等等控制,以及如何 ... [详细]
  • Android中怎么利用TextView显示部分文字高亮
    这篇文章将为大家详细讲解有关Android中怎么利用TextView显示部分文字高亮,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇 ... [详细]
author-avatar
七楼居民_651
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有