ListView是android开发中比较常用的控件,

其中适配器模式可以选择:

ArrayAdapter:简单易用,通常用于将数组或者List集合的读个包值封装成多个列表项

SimpleAdapter:其实功能很强大将数组或者List集合的读个包值封装成多个列表项

SimpleCursorAdapter:与SimpleAdapter基本类似只是用于包装Cursor提供的数据

BaseAdapter:通常用于被扩展,扩展BaseAdapter可以对各列表项进行最大的定制

而且ListView组件提供了两个很实用的功能,那就是可以在顶部和底部添加自定义的视图,今天自己做了一下小Demo加深一下这个控件的使用,实现分批显示的功能,即在一个手机屏幕下方放置一个加载更多的按钮,点击之后更新下一页的内容,详细注释均在代码中

首先定义一个activity_main.xml,为了防止listview中点击有黄色背景或者滑动出现黑色背景加了 android:cacheColorHint="#000000"      android:listSelector="@android:color/transparent"

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:paddingLeft="3dp"
    android:paddingRight="3dp" >
	<!-- 这里我们用到了Android内置名为list的id,后面要用到ListActivity -->
    <ListView
        android:id="@id/android:list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:cacheColorHint="#000000"
        android:listSelector="@android:color/transparent"/>

</LinearLayout>

然后就是list_item.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">  

    <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中单个列表的布局文件 -->

接着就是底部加载更多的视图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="更多显示请点击"
        android:onClick="loadMore"/>
</LinearLayout> 

适配器作为连接Activity和数据格式的过度器件,这里定义如下,代码中有着详细的注释

package com.xsf.listviewtest;

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;

import com.example.listviewtest.R;
/*
 * 继承BaseAdapter实例化需要Context对象来获取LayoutInflater实例和一个集合来充当适配器的数据收集
 * 在getView方法中填充list_item.xml布局文件完成每一项的数据显示
 * addItem方法用来加载数据时向数据集合中添加新的数据
 */
public class ListViewAdapter extends BaseAdapter {
	private List<String> items;
	//LayoutInflater的作用类似于 findViewById(),不同点是LayoutInflater是用来找layout文件夹下的xml布局文件,并且实例化!
	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);
	}
}

最后就是MainActivity,主要用到了 onScroll(AbsListView view, int firstVisibleItem  int visibleItemCount, int totalItemCount)其中firstVisibleItem表示在现时屏幕第一个ListItem(部分显示的ListItem也算)在整个ListView的位置(下标从0开始),visibleItemCount表示在现时屏幕可以见到的ListItem(部分显示的ListItem也算)总数,totalItemCount表示ListView的ListItem总数

package com.xsf.listviewtest;

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;

import com.example.listviewtest.R;

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();// 多线程处理handler

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		/**
		 * LayoutInflater这个类的作用类似于findViewById(), 不同点:
		 * LayoutInflater是用来找layout下xml布局文件的,而且它会实例化
		 * findViewById()是找具体xml布局文件下的具体widget控件,比如:Button按钮
		 *
		 * inflate就相当于将一个xml中定义的布局找出来.   
		 * 因为如果在一个Activity文件里直接用findViewById()这个方法的话,
		 * 那么它所对应的是setConentView()中调用的那个layout里的组件.   
		 * 因此如果在同样的Activity里用到别的layout的话,
		 * 而且你还要设置这个layout里的组件(比如:ImageView,TextView)上的内容,
		 * 那么你就必须用inflate()先将这个layout找出来, 然后再用这个layout对象去找到它上面的组件 然后进行一系列的操作
		 *
		 * inflate()方法中参数: 1.想要用的布局文件的id 2.持有选项卡的内容,获取加载视图的xml
		 * 3.null:将此处解析的xml文件不做为根视图View
		 */

		loadMoreView = getLayoutInflater().inflate(R.layout.more, null);// 每次解析都会出现新的视图不会出现引用问题
		loadMoreButton = (Button) loadMoreView
				.findViewById(R.id.loadMoreButton);
		listView = getListView(); // 获取id是list的ListView
		/*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("MORE", "loading...");
		}

	}

	/*
	 * 点击按钮的事件
	 */
	public void loadMore(View view) {
		loadMoreButton.setText("玩命加载中.....");// 设置按钮加载文字
		handler.postDelayed(new Runnable() {

			@Override
			public void run() {
				loadData();
				adapter.notifyDataSetChanged();// 数据集变化后通知adapter
				listView.setSelection(visibleLastIndex - visibleItemCount + 1);// 设置选中项
				loadMoreButton.setText("more");// 回复按钮文字

			}
		}, 3000);
	}

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

	}

}

基于BaseAdapter的Listview小Demo的更多相关文章

  1. Nancy之基于Nancy.Owin的小Demo

    前面做了基于Nancy.Hosting.Aspnet和Nancy.Hosting.Self的小Demo 今天我们来做个基于Nancy.Owin的小Demo 开始之前我们来说说什么是Owin和Katan ...

  2. 一个基于ES5的vue小demo

    由于现在很多vue项目都是基于ES6开发的,而我学vue的时候大多是看vue官网的API,是基于ES5的,所以对于刚接触项目的我来说要转变为项目的模块化写法确实有些挑战.因此,我打算先做一个基于ES5 ...

  3. 一个基于ES6+webpack的vue小demo

    上一篇文章<一个基于ES5的vue小demo>我们讲了如何用ES5,vue-router做一个小demo,接下来我们来把它变成基于ES6+webpack的demo. 一.环境搭建及代码转换 ...

  4. Nancy之基于Nancy.Hosting.Self的小Demo

    继昨天的Nancy之基于Nancy.Hosting.Aspnet的小Demo后, 今天来做个基于Nancy.Hosting.Self的小Demo. 关于Self Hosting Nancy,官方文档的 ...

  5. Nancy之基于Self Hosting的补充小Demo

    前面把Hosting Nancy with ASP.NET.Self Hosting Nancy和Hosting Nancy with OWIN 以demo的形式简单描述了一下. 这篇是为Self H ...

  6. 新手 gulp+ seajs 小demo

    首先,不说废话,它的介绍和作者就不在多说了,网上一百度一大堆: 我在这里只是来写写我这2天抽空对seajs的了解并爬过的坑,和实现的一个小demo(纯属为了实现,高手请绕道); 一.环境工具及安装 1 ...

  7. Android学习小Demo一个显示行线的自定义EditText

    今天在处理一个EditText的时候,想着把EditText做成像一本作业本上的纸一样,每一行都可以由线条隔开,具体效果如下: 1)最开始的思路 一开始的想法是很简单的,找出每一行的高度,然后一行一行 ...

  8. Android学习小Demo(19)利用Loader来实时接收短信

    之前写过一篇文章<Android学习小Demo(13)Android中关于ContentObserver的使用>,在里面利用ContentOberver去监測短信URI内容的变化.我们先来 ...

  9. Android -BLE蓝牙小DEMO

    代码地址如下:http://www.demodashi.com/demo/13890.html 原文地址: https://blog.csdn.net/vnanyesheshou/article/de ...

随机推荐

  1. [HNOI2012]射箭

    Description 沫沫最近在玩一个二维的射箭游戏,如下图 1 所示,这个游戏中的 x 轴在地面,第一象限中有一些竖直线段作为靶子,任意两个靶子都没有公共部分,也不会接触坐标轴.沫沫控制一个位于( ...

  2. POI ZAW

    要求一个最短路,担心的就是一条边被正反经过两次. 规定第一步为1到i,并把这条边设为不可经过.然后从i做最短路到1,因为这个过程是不会经历重边的(如果经历了就不是最短路了). 求最短路用SPFA,但常 ...

  3. Codeforces Round #402 (Div. 1)

    A题卡壳了,往离线倒着加那方面想了会儿,后来才发现方向错了,二十多分钟才过掉,过了B后做D,想法好像有点问题,最后只过两题,掉分了,差一点回紫. AC:AB Rank:173 Rating:2227- ...

  4. Codeforces278E Tourists

    来自FallDream的博客,未经允许,请勿转载,谢谢. 给定一张无向图,有点权,要支持单点修改点权和询问从一个点到另一个点不重复经过节点的路径上点权最小值的最小值. n,m<=10^5 考虑求 ...

  5. ESLint规范

    配置如下:{ // 环境定义了预定义的全局变量. "env": { //环境定义了预定义的全局变量.更多在官网查看 "browser":true, " ...

  6. Amazon新一代云端关系数据库Aurora(上)

    本文由  网易云发布. 在2017年5月芝加哥举办的世界顶级数据库会议SIGMOD/PODS上,作为全球最大的公有云服务提供商,Amazon首次系统的总结 了新一代云端关系数据库Aurora的设计实现 ...

  7. Python中高阶函数讲解

    高阶函数讲解 1. 常规高阶函数 递归函数 格式:def func_name(variable): '''__doc__'''#函数的说明文档 if 条件表达式:#限制递归退出值 pass retur ...

  8. 图像融合之拉普拉斯融合(laplacian blending)

    一.拉普拉斯融合基本步骤 1. 两幅图像L,R,以及二值掩模mask,给定金字塔层数level. 2. 分别根据L,R构建其对应的拉普拉斯残差金字塔(层数为level),并保留高斯金字塔下采样最顶端的 ...

  9. JAVA的Date类与Calendar类(常用方法)

    http://blog.csdn.net/xiaopihai86/article/details/50827945 1.用Java.util.Calender来实现      Calendar cal ...

  10. 运行eclipse java virtual machine launcher 什么错误

    在MyEclipse的安装目录eclipse有个eclipse.ini文件原来的配置如下:-showsplashcom.genuitec.myeclipse.blue.product.ide--lau ...