Andorid上拉加载更多的几种实现方式

1.前言

Andriod中上拉加载更多的效果随处可见,因为一次性要展现的数据太多信息量太大的话,给用户的体验就很差(加载慢,界面卡顿、流量消耗大等),而加载更多可以控制每次加载条目的数量以达到快速加载,底部加载更多的方式就显得更人性化,今天就把用过的几种方式总结一下.

2.上拉加载更多的实现方式

  1. ListView控件;作为一种传统列表展现的方式,ListView控件的addHeaderView(...)、addFooterView(...)方法很方便的支持头布局、脚布局,参数就是打气筒打出来的布局.这个很常见,也算是一种屡试不爽的方式.
  2. RecyclerView控件;它是Android5.0以后推出的新控件,在v7包中,可以完美向下兼容,相比于ListView可定制性更大.并且RecyclerView本身不参与任何视图相关的问题,它不关心如何将子View放在合适的位置,也不关心如何分割这些子View,更不关心每个子View各自的外观。更进一步来说就是RecyclerView它只负责回收和重用的工作,这也是它名字的由来.

     它并没有现成的下拉刷新和上拉加载的实现.下拉刷新可以配合SwipeRefreshView实现,这个较简单,来看下RecyclerView的加载更多实现方式.

思路:recyclerView.addOnScrollListener(...),通过监听recyclerview的滚动状态,判断是滚动状态且最后可见条目是最后一条时,加载更多.

final LinearLayoutManager layoutManager = new LinearLayoutManager(this);        recyclerView = (RecyclerView) findViewById(R.id.recyclerView);        recyclerView.setLayoutManager(layoutManager);        recyclerView.setAdapter(adapter);        recyclerView.setHasFixedSize(true);

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

@Override            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {                Log.d("==MainActivity==", "onScrolledStart");              super.onScrolled(recyclerView, dx, dy);                int lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition();                int count = adapter.getItemCount();                if (lastVisibleItemPosition + 1 == count )                {                    Log.d("==MainActivity==", "loading excute");                    if (!isLoading) {                        isLoading = true;                        handler.postDelayed(new Runnable() {                            @Override                            public void run() {                                isLoading = false;                                //加载更多数据                                addData();                            }                        }, 2000);

}                }

}        });
public void addData() {    adapter.addData(originalData);}

public class RecyclerViewAdapter extends RecyclerView.Adapter<ViewHolder> {    private static final int TYPE_ITEM = 0;    private static final int TYPE_FOOTER = 1;    private Context context;    private List<Map<String,Object>> datas;

public RecyclerViewAdapter(Context context) {        this.context = context;

datas = new ArrayList();    }

public void addData(List data) {        datas.addAll(data);        this.notifyItemRangeChanged(0, datas.size());    }

public interface OnItemClickListener {        void onItemClicked(View view, int position);

void onItemLongClicked(View view, int position);    }

private OnItemClickListener onItemClickListener;

public void setOnItemClickListener(OnItemClickListener onItemClickListener) {        this.onItemClickListener = onItemClickListener;    }

@Override    public int getItemCount() {        int aa = datas.size() == 0 ? 0 : datas.size() + 1;        return aa;

}

@Override    public int getItemViewType(int position) {        if (position + 1 == getItemCount()) {            return TYPE_FOOTER;        } else {            return TYPE_ITEM;        }    }

@Override    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        //加载每个列表项        if (viewType == TYPE_ITEM) {            View view = LayoutInflater.from(context).inflate(R.layout.item_base, parent, false);            return new ItemViewHolder(view);        }        if (viewType == TYPE_FOOTER) {            View view = LayoutInflater.from(context).inflate(R.layout.item_foot, parent, false);            return new FootViewHolder(view);        }        return null;    }

@Override    public void onBindViewHolder(final ViewHolder holder, int position) {        //加载每个列表项的数据        if (holder instanceof ItemViewHolder) {

Map<String, Object> listItem = datas.get(position);            ((ItemViewHolder) holder).name.setText((String)listItem.get("personName") + "  ------------" + String.valueOf(position));            ((ItemViewHolder) holder).decs.setText((String)listItem.get("desc"));            ((ItemViewHolder) holder).header.setImageResource((int)listItem.get("header"));            if (onItemClickListener != null) {                holder.itemView.setOnClickListener(new View.OnClickListener() {                    @Override                    public void onClick(View v) {                        int position = holder.getLayoutPosition();                        onItemClickListener.onItemClicked(holder.itemView, position);                    }                });

holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {                    @Override                    public boolean onLongClick(View v) {                        int position = holder.getLayoutPosition();                        onItemClickListener.onItemLongClicked(holder.itemView, position);                        return false;                    }                });            }        }    }

static class ItemViewHolder extends ViewHolder {        TextView name;        TextView decs;        ImageView header;

public ItemViewHolder(View view) {            super(view);            decs = (TextView)view.findViewById(R.id.desc);            name = (TextView)view.findViewById(R.id.name);            header = (ImageView)view.findViewById(R.id.header);        }    }

static class FootViewHolder extends ViewHolder {

public FootViewHolder(View view) {            super(view);        }    }}

值得注意的就是getItemCount()方法返回的是数据总条目数+1,getItemViewType(int position) 方法返回当前position对应的条目类型,既然要底部加载更多,那就是2种不同的类型;而onCreateViewHolder(ViewGroup parent, int viewType) 肯定是返回对应的这两种ViewHolder;onBindViewHolder方法就是依据holder决定绑定对应怎样的视图.
  3.对RecyclerView二次封装的开源框架;常用的有UltimateRecyclerView(解决RecyclerView下拉刷新,加载更多,增加头部,显示或隐藏工具栏等许多问题的知名开源框架)、  PullLoadMoreRecyclerView(属性最全,实现了RecyclerView下拉刷新和上拉加载更多以及RecyclerView线性、网格、瀑布流效果)、SwipeToLoadLayout支持多种基于RecyclerView的上拉加载和下拉刷新样式;

  以PullLoadMoreRecyclerView为例子简单介绍其使用方式:  build.gradle添加依赖:

   dependencies {

    compile ‘com.wuxiaolong.pullloadmorerecyclerview:library:1.0.4‘

   }

  设置线性布局(当然也有网格布局、瀑布流效果)

    mPullLoadMoreRecyclerView = (PullLoadMoreRecyclerView) view.findViewById(R.id.pullLoadMoreRecyclerView);

    mPullLoadMoreRecyclerView.setLinearLayout();

  绑定适配器,适配器的写法,这个没什么特别的,继承RecyclerView.Adapter就好了

   调用下拉刷新和加载更多(...啥也不说了,这接口暴露的多好...)

    mPullLoadMoreRecyclerView.setOnPullLoadMoreListener(new PullLoadMoreRecyclerView.PullLoadMoreListener() {

            @Override

            public void onRefresh() {//下拉刷新时调用

            }

            @Override

            public void onLoadMore() {//上拉加载更多时调用               

            }

        })

  mPullLoadMoreRecyclerView.setPullLoadMoreCompleted();//加载结束时调用  此外还有很多个性化的接口方法暴露,很方便开发时使用.这里就不一一介绍了.具体可以去Github上搜索.
3.总结按时间来说,我用得最多的是ListView,但是头布局越来越多后,position的转换显得很麻烦,而且recyclerview的缓存和回收机制更高效,recyclerview早就挡不住了,listview和Gridview正在被recycleview替代,了解一些优秀的开源框架对开发事半功倍,但是我要强调的是这些框架的具体实现原理如果搞懂的话,可以形成自己的东西,有时间自己也能写出高效的框架来.后面也会深入理解.


 
时间: 2025-01-13 17:29:41

Andorid上拉加载更多的几种实现方式的相关文章

android 安卓 listview 支持下拉刷新 上拉加载更多

[1]重写listView import java.text.SimpleDateFormat; import java.util.Date; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.ViewGrou

android ListView上拉加载更多 下拉刷新功能实现(采用pull-to-refresh)

Android实现上拉加载更多功能以及下拉刷新功能, 采用了目前比较火的PullToRefresh,他是目前实现比较好的下拉刷新的类库. 目前他支持的控件有:ListView, ExpandableListView,GridView,WebView等. 下载地址:https://github.com/chrisbanes/Android-PullToRefresh 首先第一步当然是导入libriay到咱们的项目了,具体导入方式,这里不再赘述. 下面是个例子采用的是ListView,当然其余的和这

下拉刷新与上拉加载更多

代码如下: /** * ListView下拉刷新和加载更多 * <p> * * <strong>变更说明:</strong> * <p> * 默认如果设置了OnRefreshListener接口和OnLoadMoreListener接口 * <p> * 剩余三个Flag: <br> * mIsAutoLoadMore(是否自动加载更多) <br> * mIsMoveToFirstItemAfterRefresh(下拉刷新后

Android实战简易教程-第五十三枪(通过实现OnScrollListener接口实现上拉加载更多功能)

支持上拉加载更多的控件有很多,但是你知道背后的原理吗?有一些面试官可能会问到这方便的知识,他们认为会用不是目的,懂背后的原理才是真人才.下面我们通过实现OnScrollListener接口实现上拉加载更多的效果,这里用到了回调接口,你需要对回调进行比较好的理解,回调机制是Android中很重要的机制,下面我们看一下代码: 1.定义一个footer.xml,用于下拉提示的效果: <?xml version="1.0" encoding="utf-8"?>

android 下拉刷新上拉加载更多,高仿ios左滑动删除item,解决了众多手势问题

一.前言 老规矩,别的不说,这demo是找了很相关知识集合而成的,可以说对我这种小白来说是绞尽脑汁!程序员讲的是无图无真相!现在大家一睹为快! 二.比较关键的还是scroller这个类的 package com.icq.slideview.view; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.util.TypedValue; i

移动端touch事件 || 上拉加载更多

前言: 说多了都是泪,在进行项目开发时,在上拉加载更多实现分页效果的问题上,由于当时开发任务紧急,所以就百度找了各种移动端的上拉下拉 实现加载更多的插件.然后就留下了个坑:上拉加载的时候会由于用户错误的姿势,例如长按后再touchmove等会出现卡死的假象.(ps:当然, 我不认为是插件的问题,当时的想法是觉得引用的插件存在冲突),于是,我就直接通过封装touch事件完成上拉加载实现分页的功能. 备注:文章最后会加上为实现这个功能我找的一些插件 了解touch事件 在应用touch事件实现上拉加

Android上拉加载更多ListView——PulmListView

思路 今天带大家实现一个上拉加载更多的ListView.GitHub传送门:PulmListView, 欢迎大家fork&&star. 先带大家理一下思路, 如果我们要实现一个上拉加载更多的ListView, 我们需要实现的功能包括: 一个自定义的ListView, 并且该ListView能够判断当前是否已经处于最底部. 一个自定义的FooterView, 用于在ListView加载更多的过程中进行UI展示. 关联FooterView和ListView, 包括加载时机判断.FooterVi

Android中自定义ListView实现上拉加载更多和下拉刷新

ListView是Android中一个功能强大而且很常用的控件,在很多App中都有ListView的下拉刷新数据和上拉加载更多这个功能.这里我就简单记录一下实现过程. 实现这个功能的方法不止一个,GitHub上有一些开源库可以使用,但是本着学习的精神,我做的是使用自定义ListView实现这个功能. 思路:谷歌提供的ListView是不能提供下拉刷新和下拉加载的,所以我们就需要重写ListView.在ListView的头部和尾部加上我们的布局文件(progressbar). 先说上拉加载更多实现

vue2.0 移动端,下拉刷新,上拉加载更多插件,修改版

在[实现丰盛]的插件基础修改[vue2.0 移动端,下拉刷新,上拉加载更多 插件], 1.修改加载到尾页面,返回顶部刷新数据,无法继续加重下一页 2.修改加载完成文字提示 原文链接:http://www.cnblogs.com/sichaoyun/p/6647458.html <template lang="html"> <div class="yo-scroll" :class="{'down':(state===0),'up':(st