文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android之ListView分页加载数据功能实现代码

2022-06-06 07:51

关注

什么是ListView分页加载数据功能呢?在现在的大数据时代,我们不可能把某些数据全部展示到界面,好比我们经常会看的QQ空间一样,当你看动态的时候,系统不可能会把所有好友的动态都展示在上面,你能看到的一般都是最新好友更新的动态,假如你要看非最新的好友动态,通常你都会手指向上滑动屏幕然后去查看,当界面下滑到一定数量的时候,就会看到一个“查看更多”,然后突然停顿一下,系统会通过网络去给你刷新其他动态信息,这样的功能我们一般叫做数据下拉刷新功能,也就是我们的分页加载功能,具体的实现是怎样的呢?下面我们开始详细讲解。

实现的原理:

1. 首先要先确定默认展示在ListView上的数据,比如默认在ListView上展示10条数据。
2. 将数据传递到自定义的适配器上,然后加载到ListView中。
3. 当用户将数据拉到最后一条的时候,就要开始刷新加载新数据了。
4. 通过监听ListView的滑动事件,判断是否达到最后一条,如果达到最后一条则开始刷新。

详细的实现步奏在代码中详细讲解。

整体结构如下:

activity_main.xml


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 tools:context="com.company.listviewdeepknow.MainActivity">
 <ListView
  android:id="@+id/mList"
  android:layout_width="match_parent"
  android:layout_height="match_parent">
 </ListView>
</RelativeLayout>

foot_boot.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="70dp"
 android:gravity="center"
 android:orientation="horizontal">
 <ProgressBar
  android:id="@+id/progressBar"
  style="?android:attr/progressBarStyleSmall"
  android:layout_width="45dp"
  android:layout_height="45dp" />
 <TextView
  android:id="@+id/mLoad"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="加载更多..."
  android:textSize="20sp" />
</LinearLayout>

list_item.xml


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="horizontal">
 <TextView
  android:id="@+id/mTv1"
  android:layout_width="100dp"
  android:layout_height="100dp"
  android:textSize="20sp" />
 <TextView
  android:id="@+id/mTv2"
  android:layout_width="100dp"
  android:layout_height="100dp"
  android:layout_alignParentRight="true"
  android:textSize="20sp" />
</RelativeLayout>

MainActivity.java


public class MainActivity extends AppCompatActivity implements MyOnScrollListener.OnloadDataListener {
 //ListView展示的数据项
 private List<Student> data;
 //ListView控件
 private ListView mList;
 //自定义适配器
 MyAdapter adapter;
 //底部加载更多布局
 View footer;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  //首先加载默认数据,这里设置为10条
  getData();
  //显示到ListView上
  showListView(data);
  //自定义的滚动监听事件
  MyOnScrollListener onScrollListener = new MyOnScrollListener(footer, data);
  //设置接口回调
  onScrollListener.setOnLoadDataListener(this);
  //设置ListView的滚动监听事件
  mList.setOnScrollListener(onScrollListener);
 }
 
 private void getData() {
  data = new ArrayList<>();
  Student stu = null;
  for (int i = 0; i < 10; i++) {
   stu = new Student();
   stu.setName("姓名" + i);
   stu.setSex(i % 2 == 0 ? "男" : "女");
   data.add(stu);
  }
 }
 
 private void showListView(List<Student> data) {
  //首先判断适配器是否为空,首次运行肯定是为空的
  if (adapter == null) {
   //查到ListView控件
   mList = (ListView) findViewById(R.id.mList);
   //将底部加载一个加载更多的布局
   footer = LayoutInflater.from(this).inflate(R.layout.foot_boot, null);
   //初始状态为隐藏
   footer.setVisibility(View.GONE);
   //加入到ListView的底部
   mList.addFooterView(footer);
   //创建adpter数据
   adapter = new MyAdapter(data);
   //设置adapter
   mList.setAdapter(adapter);
  } else {
   //不为空,则刷新数据
   this.data = data;
   //提醒ListView重新更新数据
   adapter.notifyDataSetChanged();
  }
 }
 @Override
 public void onLoadData(List<Student> data) {
  //加载数据完成后,展示数据到ListView
  showListView(data);
 }
}

MyOnScrollListener.java


public class MyOnScrollListener implements AbsListView.OnScrollListener {
 //ListView总共显示多少条
 private int totalItemCount;
 //ListView最后的item项
 private int lastItem;
 //用于判断当前是否在加载
 private boolean isLoading;
 //底部加载更多布局
 private View footer;
 //接口回调的实例
 private OnloadDataListener listener;
 //数据
 private List<Student> data;
 public MyOnScrollListener(View footer, List<Student> data) {
  this.footer = footer;
  this.data = data;
 }
 //设置接口回调的实例
 public void setOnLoadDataListener(OnloadDataListener listener) {
  this.listener = listener;
 }
 
 @Override
 public void onScrollStateChanged(AbsListView view, int scrollState) {
  //如果数据没有加载,并且滑动状态是停止的,而且到达了最后一个item项
  if (!isLoading && lastItem == totalItemCount && scrollState == SCROLL_STATE_IDLE) {
   //显示加载更多
   footer.setVisibility(View.VISIBLE);
   Handler handler = new Handler();
   //模拟一个延迟两秒的刷新功能
   handler.postDelayed(new Runnable() {
    @Override
    public void run() {
     if (listener != null) {
      //开始加载更多数据
      loadMoreData();
      //回调设置ListView的数据
      listener.onLoadData(data);
      //加载完成后操作什么
      loadComplete();
     }
    }
   }, 2000);
  }
 }
 
 private void loadComplete() {
  isLoading = false;
  footer.setVisibility(View.GONE);
 }
 
 private void loadMoreData() {
  isLoading = true;
  Student stu = null;
  for (int i = 0; i < 3; i++) {
   stu = new Student();
   stu.setName("新名字" + i);
   stu.setSex("新性别" + i);
   data.add(stu);
  }
 }
 
 @Override
 public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
  //当可见界面的第一个item + 当前界面多有可见的界面个数就可以得到最后一个item项了
  lastItem = firstVisibleItem + visibleItemCount;
  //总listView的item个数
  this.totalItemCount = totalItemCount;
 }
 //回调接口
 public interface OnloadDataListener {
  void onLoadData(List<Student> data);
 }
}

MyAdapter.java


public class MyAdapter extends MyBaseAdapter<Student> {
 public MyAdapter(List<Student> data) {
  super(data);
 }
 @Override
 public void setData(ViewHolder holder, Student t) {
  holder.setText(R.id.mTv1, t.getName()).setText(R.id.mTv2, t.getSex());
 }
}

MyBaseAdapter.java


public abstract class MyBaseAdapter<T> extends BaseAdapter {
 protected List<T> data;
 public MyBaseAdapter(List<T> data){
  this.data = data;
 }
 @Override
 public int getCount() {
  return data == null ? 0 : data.size();
 }
 @Override
 public Object getItem(int position) {
  return data.get(position);
 }
 @Override
 public long getItemId(int position) {
  return position;
 }
 @Override
 public View getView(int position, View convertView, ViewGroup parent) {
  ViewHolder holder = ViewHolder.getHolder(convertView,parent,position, R.layout.list_item);
  setData(holder,data.get(position));
  return holder.getConvertView();
 }
 public abstract void setData(ViewHolder holder,T t);
}

ViewHolder.java


public class ViewHolder {
 private int position;
 private SparseArray<View> array;
 private View convertView;
 private Context context;
 private ViewHolder(ViewGroup parent, int position, int layout) {
  this.position = position;
  this.context = parent.getContext();
  convertView = LayoutInflater.from(parent.getContext()).inflate(layout, null);
  convertView.setTag(this);
  array = new SparseArray<>();
 }
 public static ViewHolder getHolder(View convertView, ViewGroup parent, int position, int layout) {
  if (convertView == null) {
   return new ViewHolder(parent, position, layout);
  } else {
   ViewHolder holder = (ViewHolder) convertView.getTag();
   holder.position = position;
   return holder;
  }
 }
 public <T extends View> T getView(int viewId) {
  View view = array.get(viewId);
  if (view == null) {
   view = convertView.findViewById(viewId);
   array.put(viewId, view);
  }
  return (T) view;
 }
 public View getConvertView() {
  return convertView;
 }
 public ViewHolder setText(int viewId, String data) {
  TextView tv = getView(viewId);
  tv.setText(data);
  return this;
 }

 Student.java


public class Student {
 private String name;
 private String sex;
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public String getSex() {
  return sex;
 }
 public void setSex(String sex) {
  this.sex = sex;
 }
}

除了MyAdapter.java MyBaseAdapter.java ViewHolder.java 以及 Student.java实体类没有注解,其他两个主要实现类都已经注释了,关于自定义通用适配器的讲解,本篇不做讲解,如果想了解如何实现自定义通用适配器知识的可以查看: 

下面可以看看效果图:

您可能感兴趣的文章:Android中ListView异步加载图片错位、重复、闪烁问题分析及解决方案Android实现Listview异步加载网络图片并动态更新的方法Android程序开发ListView+Json+异步网络图片加载+滚动翻页的例子(图片能缓存,图片不错乱)Android ListView异步加载图片方法详解Android实现ListView异步加载图片的方法Android实现ListView异步加载的方法(改进版)Android实现上拉加载更多以及下拉刷新功能(ListView)Android实现ListView分页自动加载数据的方法Android ListView实现上拉加载更多和下拉刷新功能基于Android ListView之加载使用技巧Android开发实现ListView异步加载数据的方法详解


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯