熟悉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"><ListViewandroid: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);}@Overridepublic int getCount() {return items.size();}@Overridepublic Object getItem(int position) {return items.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic 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();@Overridepublic 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的ListViewlistView.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);}/** * 滑动时被调用 */@Overridepublic void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {this.visibleItemCount = visibleItemCount;visibleLastIndex = firstVisibleItem + visibleItemCount - 1;}/** * 滑动状态改变时被调用 */@Overridepublic 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...");//设置按钮文字loadinghandler.postDelayed(new Runnable() {@Overridepublic void run() {loadData();adapter.notifyDataSetChanged();//数据集变化后,通知adapterlistView.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会被调用。

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

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

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

我们看到onScrollStateChanged方法里的if语句里代码执行了,所以如果我们希望自动加载的话,可以把加载代码放于此处。

http://blog.csdn.net/liuhe688/article/details/6852523#

更多相关文章

  1. 一句话锁定MySQL数据占用元凶
  2. Android(安卓)SQLite 数据库详细介绍
  3. Android加载Bitmap出现OutofMemoryError的原因(官方译文)
  4. Android应用程序的开机自启动
  5. android中Bitmap导致的内存溢出
  6. Android(安卓)ViewPager 如何判断当前页面是从前一页还是后一页
  7. Android(安卓)Viewpage禁止滑动屏幕
  8. Android(安卓)实现自定义圆环
  9. android android 在list view中插入一条广告

随机推荐

  1. 深入理解Java的接口和抽象类
  2. zabbix yum及package模块
  3. 图解 Java 中的数据结构及原理,不懂的也能
  4. 致老男孩教育的维权声明 - Spug运维
  5. 价值200万的小米LOGO给UI设计师带来了什
  6. 4K + 书写主动画笔:EHOMEWEI 便携触摸显示
  7. k8s亲和性应用示例
  8. 禁止网页 切屏 切换标签
  9. 运维7年,对Linux的经验总结
  10. Windows 7部署Jenkins遇到的坑