Android ListView滚动到底后自动加载数据

熟悉Android的朋友们都知道,不管是微博客户端还是新闻客户端,都离不开列表组件,可以说列表组件是Android数据展现方面最重要的组件,我们 今天就要讲一讲列表组件ListView加载数据的相关内容。通常来说,一个应用在展现大量数据时,不会将全部的可用数据都呈现给用户,因为这不管对于服 务端还是客户端来说都是不小的压力,因此,很多应用都是采用分批次加载的形式来获取用户所需的数据。比如:微博客户端可能会在用户滑动至列表底端时自动加 载下一页数据,也可能在底部放置一个“加载更多”按钮,用户点击后,加载下一页数据。

我们今天就结合实例来演示一下使用ListView获取数据的过程。

新建一个loadmore项目,我们来看一下结构图和最终效果图:

左图中包含了三个布局文件、一个Adapter和一个Activity,右图是我们运行后的主界面。

其中,main.xml是主界面的布局文件,它包含一个ListView组件,代码如下:

 <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:paddingLeft="3dp"
  android:paddingRight="3dp">
  <ListView
   android:id="@id/android:list"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"/>
 </LinearLayout>

这里我们引用了Android内置的名为list的id,因为我们后面要使用到ListActivity,我们的MainActivity继承于它。
然后就是list_item.xml,它是ListView中单个列表项的布局文件,从效果图中可以看到,这里只使用到了一个TextView组件,list_item.xml代码如下:

 <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <TextView
   android:id="@+id/list_item_text"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:gravity="center"
   android:textSize="20sp"
   android:paddingTop="10dp"
   android:paddingBottom="10dp"/>
 </LinearLayout>

我们注意到在右图中列表底部有一个按钮不同于其他的列表项,这是什么情况?事实上这个按钮是我们在ListView底部添加的一个视图。 ListView组件提供了两个很实用的功能,那就是可以在顶部和底部添加自定义的视图。我们在此处ListView的底部添加了一个视图用来加载更多数 据,这个视图对应着load_more.xml布局文件,代码如下:

 <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content">
  <Button
   android:id="@+id/loadMoreButton"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:text="load more"
   android:onClick="loadMore"/>
 </LinearLayout>

接下来我们来了解一下我们的Adapter,ListViewAdapter代码如下:

 package com.scott.loadmore; 

 import java.util.List; 

 import android.content.Context;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.BaseAdapter;
 import android.widget.TextView; 

 public class ListViewAdapter extends BaseAdapter {
  private List<String> items;
  private LayoutInflater inflater; 

  public ListViewAdapter(Context context, List<String> items) {
   this.items = items;
   inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  } 

  @Override
  public int getCount() {
   return items.size();
  } 

  @Override
  public Object getItem(int position) {
   return items.get(position);
  } 

  @Override
  public long getItemId(int position) {
   return position;
  } 

  @Override
  public View getView(int position, View view, ViewGroup parent) {
   if (view == null) {
    view = inflater.inflate(R.layout.list_item, null);
   }
   TextView text = (TextView) view.findViewById(R.id.list_item_text);
   text.setText(items.get(position));
   return view;
  } 

  /**
   * 添加列表项
   * @param item
   */
  public void addItem(String item) {
   items.add(item);
  }
 }

这个ListViewAdapter是我们自定义适配器,它继承自BaseAdapter,实例化此适配器需要一个Context对象来获取 LayoutInflater实例和一个集合对象来充当适配器的数据集;在getView方法中我们填充list_item.xml布局文件,完成列表每 一项的数据显示;addItem方法用来在加载数据时向数据集中添加新数据。

最后我们来看一下MainActivity:

 package com.scott.loadmore; 

 import java.util.ArrayList; 

 import android.app.ListActivity;
 import android.os.Bundle;
 import android.os.Handler;
 import android.util.Log;
 import android.view.View;
 import android.widget.AbsListView;
 import android.widget.AbsListView.OnScrollListener;
 import android.widget.Button;
 import android.widget.ListView; 

 public class MainActivity extends ListActivity implements OnScrollListener {
  private ListView listView;
  private int visibleLastIndex = 0; //最后的可视项索引
  private int visibleItemCount;  // 当前窗口可见项总数
  private ListViewAdapter adapter;
  private View loadMoreView;
  private Button loadMoreButton;
  private Handler handler = new Handler(); 

  @Override
  public void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.main); 

   loadMoreView = getLayoutInflater().inflate(R.layout.load_more, null);
   loadMoreButton = (Button) loadMoreView.findViewById(R.id.loadMoreButton); 

   listView = getListView();    //获取id是list的ListView 

   listView.addFooterView(loadMoreView); //设置列表底部视图 

   initAdapter(); 

   setListAdapter(adapter);    //自动为id是list的ListView设置适配器 

   listView.setOnScrollListener(this);  //添加滑动监听
  } 

  /**
   * 初始化适配器
   */
  private void initAdapter() {
   ArrayList<String> items = new ArrayList<String>();
   for (int i = 0; i < 10; i++) {
    items.add(String.valueOf(i + 1));
   }
   adapter = new ListViewAdapter(this, items);
  } 

  /**
   * 滑动时被调用
   */
  @Override
  public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
   this.visibleItemCount = visibleItemCount;
   visibleLastIndex = firstVisibleItem + visibleItemCount - 1;
  } 

  /**
   * 滑动状态改变时被调用
   */
  @Override
  public void onScrollStateChanged(AbsListView view, int scrollState) {
   int itemsLastIndex = adapter.getCount() - 1; //数据集最后一项的索引
   int lastIndex = itemsLastIndex + 1;    //加上底部的loadMoreView项
   if (scrollState == OnScrollListener.SCROLL_STATE_IDLE && visibleLastIndex == lastIndex) {
    //如果是自动加载,可以在这里放置异步加载数据的代码
    Log.i("LOADMORE", "loading...");
   }
  } 

  /**
   * 点击按钮事件
   * @param view
   */
  public void loadMore(View view) {
   loadMoreButton.setText("loading..."); //设置按钮文字loading
   handler.postDelayed(new Runnable() {
    @Override
    public void run() { 

     loadData(); 

     adapter.notifyDataSetChanged(); //数据集变化后,通知adapter
     listView.setSelection(visibleLastIndex - visibleItemCount + 1); //设置选中项 

     loadMoreButton.setText("load more"); //恢复按钮文字
    }
   }, 2000);
  } 

  /**
   * 模拟加载数据
   */
  private void loadData() {
   int count = adapter.getCount();
   for (int i = count; i < count + 10; i++) {
    adapter.addItem(String.valueOf(i + 1));
   }
  }
 }

如代码所示,我们在onCreate方法被调用时获取listView组件,设置其底部视图为loadMoreView,它包含一个按钮,点击时会 触发loadMore方法调用,另外在为listView设置完适配器时,又为其设置了滑动事件监听器,滑动列表时onScroll会被调用,滑动状态改 变时onScrollStateChanged会被调用。

我们来演示一下这个加载过程:

如图,当点击完按钮后,出现加载动作,加载完之后如右图所示,新数据紧接在原数据之后。然后我们滑动到底部,加载按钮仍可工作:

最后,我们测试一下滑动列表到底部,然后松开,控制台打印如下:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android ListView 滚动条的设置详解及实例代码

    Android ListView 滚动条的设置详解 1.滚动条的属性 android:scrollbarAlwaysDrawHorizontalTrack 设置是否始终显示水平滚动条.这里用ScrollView.ListView测试均没有效果. android:scrollbarAlwaysDrawVerticalTrack 设置是否始终显示垂直滚动条.这里用ScrollView.ListView测试均没有效果. android:scrollbarDefaultDelayBeforeFade 设

  • android ListView的右边滚动滑块启用方法 分享

    多开发者不知道ListView列表控件的快速滚动滑块是如何启用的,这里Android开发网告诉大家,辅助滚动滑块只需要一行代码就可以搞定,如果你使用XML布局只需要在ListView节点中加入  android:fastScrollEnabled="true" 这个属性即可,而对于Java代码可以通过myListView.setFastScrollEnabled(true); 来控制启用,参数false为隐藏. 还有一点就是当你的滚动内容较小,不到当前ListView的3个屏幕高度时则

  • 保存ListView上次的滚动条的位置实例(必看)

    如下所示: private int select_id = 0; //定义个全局变量 @Override public void onStop() { super.onStop(); select_id = list_view.getSelectedItemPosition();//点击列表的时候,保存位置 } @Override public void onResume() { super.onResume(); view.setSelection(select_id);//关闭画面,回到li

  • android开发之横向滚动/竖向滚动的ListView(固定列头)

    由于项目需要,我们需要一个可以横向滚动的,又可以竖向滚动的 表格.而且又要考虑大数据量(行)的展示视图.经过几天的研究终于搞定,做了一个演示.贴图如下:      好吧.让我们看思路是什么样的: 1. 上下滚动直接使用 listView来实现. 2. 左右滚动使用HorizontalScrollView,来处理滚动.我写一个类MyHScrollView继承 自它. 2.1 . ListView里的每行(row)分为 两部分,不滚动的和可滚动的区域.比如本demo的第一列,就是静态的.而后面的所有

  • Android ListView滚动到指定的位置

    本文介绍的关于ListView移动到指定位置有两种方法,下面话不多说,直接来看示例代码: listview.setSelection(position); listview.smoothScrollToPosition(position); 第一种方法没有滚动效果,直接跳到指定位置,第二种方法是有滚动效果的. 但是,在是用的时候,你会发现第二种方法没有效果,甚至都没有移动,其实这个问题很好解决,只要在新线程里是用就可以了 listview.post(new Runnable() { @Overr

  • Android简单记录和恢复ListView滚动位置的方法

    本文实例讲述了Android简单记录和恢复ListView滚动位置的方法.分享给大家供大家参考,具体如下: 有时候我们需要记录当前ListView滚动到的位置,重新加载的时候要回到原位,不罗嗦,给出代码: //列表滚动 private OnScrollListener ScrollLis = new OnScrollListener() { @Override public void onScroll(AbsListView arg0, int arg1, int arg2, int arg3)

  • android listview 水平滚动和垂直滚动的小例子

    网上有很多解决 android listview 水平和垂直滚动的代码,我没有按照他们说的做(以前没搜到 O(∩_∩)O~) 我采用的是添加HorizontalScrollViewJava代码 复制代码 代码如下: < ScrollView android:id="@+id/ScrollView01" android:layout_height="300px" android:layout_x="16px" android:layout_y

  • Android ListView滚动到底后自动加载数据

    熟悉Android的朋友们都知道,不管是微博客户端还是新闻客户端,都离不开列表组件,可以说列表组件是Android数据展现方面最重要的组件,我们 今天就要讲一讲列表组件ListView加载数据的相关内容.通常来说,一个应用在展现大量数据时,不会将全部的可用数据都呈现给用户,因为这不管对于服 务端还是客户端来说都是不小的压力,因此,很多应用都是采用分批次加载的形式来获取用户所需的数据.比如:微博客户端可能会在用户滑动至列表底端时自动加 载下一页数据,也可能在底部放置一个"加载更多"按钮,

  • 基于AngularJS实现页面滚动到底自动加载数据的功能

    要实现这个功能,可以通过 https://github.com/sroze/ngInfiniteScroll 这个第三方控件来实现.步骤如下: 1. 下载ng-infinite-scroll.js程序 http://sroze.github.io/ngInfiniteScroll/ 目前版本是1.0.0 2. 如果你是用的jQuery2.0以上版本,还需要修改ng-infinite-scroll.js程序,将所有的将所有的$window.xxx改为$(window).xxx, elem.xxx改

  • Android圆形头像拍照后“无法加载此图片”的问题解决方法(适配Android7.0)

    Feature: 点击选择拍照或者打开相册,选取图片进行裁剪最后设置为圆形头像. Problem: 拍好照片,点击裁剪,弹Toast"无法加载此图片". Solution: 在裁剪的class里加两行代码 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 主要代码如下: public static final S

  • ASP.NET Core中修改配置文件后自动加载新配置的方法详解

    前言 在 ASP.NET Core 默认的应用程序模板中, 配置文件的处理如下面的代码所示: config.AddJsonFile( path: "appsettings.json", optional: true, reloadOnChange: true ); config.AddJsonFile( path: $"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: t

  • jquery在启动页面时,自动加载数据的实例

    其实,重要的就是这个方法: $(document).ready(function(){ } 具体的在jquery中: 具体的ajax怎么使用,可以查看我的上一篇博客<浅谈ajax在jquery中的请求和servlet中的响应> <script type="text/javascript"> $(document).ready(function(){ var str = ""; var strA = ""; $.ajax({

  • iOS列表上拉(平滑加载数据)自动加载数据的问题解决

    项目需求 我的的列表需要改变,原来的分页加载采用的是MJRefresh框架进行加载更多数据,这需要有一个上拉动作才能触发,而我的产品的意思是当快要滑动到底部时自动加载下一页数据.我自己看了一下,发现很多app都是采用这种模式. 关于MJRefresh MJRefresh中并没有这样的方法,所以这个效果不一定是MJRefresh实现的,没有实现的小伙伴就不要在MJRefresh中苦苦寻找了. 功能实现 实现方法很简单,需要用到tableView的一个代理方法,就可轻松实现.- (void)tabl

  • Android实现ListView分页自动加载数据的方法

    Android应用开发中,采用ListView组件来展示数据是很常用的功能,当一个应用要展现很多的数据时,一般情况下都不会把所有的数据一次就展示出来,而是通过分页的形式来展示数据,个人觉得这样会有更好的用户体验.因此,很多应用都是采用分批次加载的形式来获取用户所需的数据.例如:微博客户端可能会在用户滑动至列表底端时自动加载下一页数据,也可能在底部放置一个"查看更多"按钮,用户点击后,加载下一页数据. 下面通过一个Demo来展示ListView功能如何实现:该Demo通过在ListVie

  • 基于jquery实现页面滚动到底自动加载数据的功能

    现在,我们经常使用的微博.微信或其他应用都有异步加载功能,简而言之,就是我们在刷微博或微信时,移动到界面的顶端或低端后程序通过异步的方式进行加载数据,这种方式加快了数据的加载速度,由于它每次只加载一部分数据,当我们有大量的数据,但不能显示所有,这时我们可以考虑使用异步方式加载数据. 数据异步加载可以发生在用户点击"查看更多"按钮或滚动条滚动到窗口的底部时自动加载:在接下来的博文中,我们将介绍如何实现自动加载更多的功能. 图1 微博加载更多功能 正文 假设,在我们的数据库中存放着用户的消

  • jquery 页面滚动到底部自动加载插件集合

    很多社交网站都使用无限滚动的翻页技术来提高用户体验,当你页面滑到列表底部时候无需点击就自动加载更多的内容.下面为你推荐 10 个 jQuery 的无限滚动的插件: 1. jQuery ScrollPagination jQuery ScrollPagination plugin 是一个 jQuery 实现的支持无限滚动加载数据的插件. 2. jQuery Screw Screw (scroll + view) 是一个 jQuery 插件当用户滚动页面的时候加载内容,是一个无限滚动翻页的插件. 3

  • jQuery结合AJAX之在页面滚动时从服务器加载数据

     简介 文本将演示怎么在滚动滚动条时从服务器端下载数据.用AJAX技术从服务器端加载数据有助于改善任何web应用的性能表现,因为在打开页面时,只有一屏的数据从服务器端加载了,需要更多的数据时,可以随着用户滚动滚动条再从服务器端加载. 背景 是Facebook促使我写出了在滚动条滚动时再从服务器加载数据的代码.浏览facebook时,我很惊讶的发现当我滚动页面时,新的来自服务器的数据开始插入到此现存的数据中.然后,对于用c#实现同样的功能,我在互联网上了查找了相关信息,但没有发现任何关于用c#实现

随机推荐