ListView对数据库读取实现分页滑动(8)

                    在对数据库读取中,分页滑动是十分重要的,例如你浏览空间时,往下拖动有时就会出现正在加载中字样,这种是正在像服务器数据库中读取数据现象,而且规定了每页只显示多少数据,有时网速不好还要加载很长时间

如图:

我们今天要做的就是要把之前学的数据库结合起来再加上ListView+ScrollView监听事件结合起来,自己做一个加载事件。

首先定义Activity程序中的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:id="@+id/mylayout"
	android:orientation="vertical" 
	android:layout_width="fill_parent"
	android:layout_height="fill_parent">
</LinearLayout> 

 然后定义ListView模板,就是我们之前学的

<?xml version="1.0" encoding="utf-8"?>
<TableLayout 
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:id="@+id/mylayout"
	android:orientation="vertical" 
	android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	<TableRow>
		<TextView
			android:id="@+id/id"
			android:textSize="30px"
			android:layout_height="wrap_content"
			android:layout_width="50px"/>
		<TextView
			android:id="@+id/name"
			android:textSize="30px"
			android:layout_height="wrap_content"
			android:layout_width="130px"/>
		<TextView
			android:id="@+id/birthday"
			android:textSize="30px"
			android:layout_height="wrap_content"
			android:layout_width="180px"/>
	</TableRow>
</TableLayout>

 定义数据查询类

主要实现:getCount查询出所有满足条件的记录数

                  find方法,根据用户给的两个分页参数  当前页currentPage和每页显示的记录数lineSize,查询出所有相关数据,并将数据设置到List<Map<String,Object>集合,以便在ListView添加,总结就是我先给你一页数据,一页数据15个你先用listview显示,然后你显示完通知我,利用scrollview,我再给你一页数据如此

数据查询类就是给页类代码如下:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

public class MytabCursor {
	private static final String TABLENAME = "mytab" ;
	private SQLiteDatabase db = null ;
	public MytabCursor(SQLiteDatabase db) {
		this.db = db ;
	}
	
	public int getCount() { // 返回记录数
		int count = 0;
		String sql = "SELECT COUNT(id) FROM " + TABLENAME; // 查询SQL
		Cursor result = this.db.rawQuery(sql, null);
		for (result.moveToFirst(); !result.isAfterLast(); result.moveToNext()) { // 采用循环的方式检索数据
			count = result.getInt(0);
		}
		return count;
	}
	
	public List<Map<String,Object>> find(int currentPage,int lineSize){
		List<Map<String,Object>> all = new ArrayList<Map<String,Object>>() ;
		String sql = "SELECT id,name,birthday FROM " + TABLENAME
				+ " LIMIT ?,?";
		String args[] = new String[] {
				String.valueOf((currentPage - 1) * lineSize),
				String.valueOf(lineSize) }; // 是设置参数
	/*
	 * 只查询开头数为第(currentPage - 1) * lineSize)个,只查询lineSize这么多个
	 */
		Cursor result = this.db.rawQuery(sql, args); // 执行查询语句
		for (result.moveToFirst(); !result.isAfterLast(); result.moveToNext()) {	// 采用循环的方式检索数据
			Map<String,Object> map = new HashMap<String,Object>() ;
			map.put("id", result.getInt(0)) ;
			map.put("name", result.getString(1)) ;
			map.put("birthday",result.getString(2)) ;
			all.add(map) ;
		}
		this.db.close() ;
		return all ;
	}

}

 然后是Activity主程序,进行分页显示:

public class MySQLiteDemo extends Activity {
	private ListView listView ;
	private SimpleAdapter simpleAdapter = null ;
	private LinearLayout loadLayout = null ;	// 读取的脚标的视图
	private TextView loadInfo = null ;	// 进行信息提示
	private List<Map<String,Object>> all = null ;
	private LayoutParams layoutParams = new LinearLayout.LayoutParams(
			LinearLayout.LayoutParams.FILL_PARENT,
			LinearLayout.LayoutParams.WRAP_CONTENT);	// 表示新组件的布局参数
	private SQLiteOpenHelper helper = null ;
	private LinearLayout mylayout = null ;
	private int currentPage = 1 ;
	private int lineSize = 15 ;//每页显示15条数据
	private int allRecorders = 0 ;//保存全部记录数
	private int pageSize = 1 ;	// 默认在一共只有1页
	private int lastItem = 0 ;	// 保存最后一项
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		super.setContentView(R.layout.main);
		this.mylayout = (LinearLayout) super.findViewById(R.id.mylayout) ;
		//脚标提示代码布局管理
		this.loadLayout = new LinearLayout(this) ;	// 定义脚标的线性布局管理器
		this.loadInfo = new TextView(this) ;	// 文本组件
		this.loadInfo.setText("数据加载中ing...") ;	// 定义提示文字
		this.loadInfo.setGravity(Gravity.CENTER) ;	// 文字居中显示
		this.loadInfo.setTextSize(30.0f) ;	// 文字大小
		this.loadLayout.addView(this.loadInfo,this.layoutParams) ;	// 增加组件
		this.loadLayout.setGravity(Gravity.CENTER) ;
		
		this.showAllData() ;	// 数据显示
		this.pageSize = (this.allRecorders + this.lineSize - 1)
				/ this.lineSize; // 计算总页数
		System.out.println("pageSize = " + this.pageSize) ;
		System.out.println("allRecorders = " + this.allRecorders); 
	}
	private void showAllData(){	// 读取全部的数据
		MySQLiteDemo.this.helper = new MyDatabaseHelper(MySQLiteDemo.this);
		MytabCursor cur = new MytabCursor(	// 实例化查询
				MySQLiteDemo.this.helper.getReadableDatabase()) ;	// 取得SQLiteDatabase对象
		this.allRecorders = cur.getCount() ;	// 取得全部记录数
		this.listView = new ListView(MySQLiteDemo.this) ;
		MySQLiteDemo.this.all = cur.find(MySQLiteDemo.this.currentPage,MySQLiteDemo.this.lineSize) ;
		this.listView.addFooterView(this.loadLayout) ;	// 增加读取数据的布局文件
		this.simpleAdapter = new SimpleAdapter(MySQLiteDemo.this, 	// 上下文对象
				MySQLiteDemo.this.all,			// 所有要操作的数据
				R.layout.tab_info,				// 布局管理器 
				new String[] { "id", "name", "birthday" },	// map中的key
				new int[] { R.id.id, R.id.name, R.id.birthday }) ;
		this.listView.setAdapter(this.simpleAdapter);	// 布局管理中的id
		//将已经能滚动的listview再次添加scroll的监听器
		this.listView.setOnScrollListener(new OnScrollListenerImpl()) ;
		this.mylayout.addView(listView) ;
	}
	private class OnScrollListenerImpl implements OnScrollListener{

		@Override
		public void onScroll(AbsListView view, int firstVisibleItem,
				int visibleItemCount, int totalItemCount) {
			MySQLiteDemo.this.lastItem = firstVisibleItem + visibleItemCount - 1 ;	// 统计是否到最后
		}

		@Override
		public void onScrollStateChanged(AbsListView view, int scrollState) {
			if (MySQLiteDemo.this.lastItem == MySQLiteDemo.this.simpleAdapter
					.getCount()// 已经是最底部
					&& MySQLiteDemo.this.currentPage < MySQLiteDemo.this.pageSize 	// 还有数据没读取完
					&& scrollState == OnScrollListener.SCROLL_STATE_IDLE ) {	// 不再滑动
				MySQLiteDemo.this.currentPage ++ ;
				MySQLiteDemo.this.listView.setSelection(MySQLiteDemo.this.lastItem) ;	// 设置显示位置
				MySQLiteDemo.this.appendData() ;	// 增加数据
			}
		}
		
	}
	
	private void appendData(){	// 增加数据
		MytabCursor cur = new MytabCursor(	// 实例化查询
				MySQLiteDemo.this.helper.getReadableDatabase()) ;	// 取得SQLiteDatabase对象
		List<Map<String, Object>> newData = cur.find(this.currentPage,
				this.lineSize);
		this.all.addAll(newData) ;	// 集合改变
		this.simpleAdapter.notifyDataSetChanged() ;	// 通知记录改变
	}
}

 之后建表

实例化数据表
格式

package org.lxh.demo;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class MyDatabaseHelper extends SQLiteOpenHelper {
	private static final String DATABASENAME = "mldn.db" ;
	private static final int DATABASERVERSION = 2 ;	// 设置数据库的版本
	private static final String TABLENAME = "mytab" ;
	
	public MyDatabaseHelper(Context context) {	// 用户最关心的也肯定只是Context
		super(context, DATABASENAME, null, DATABASERVERSION);
	}

	@Override
	public void onCreate(SQLiteDatabase db) {	// 创建数据表
		String sql = "CREATE TABLE " + TABLENAME + "("
				+ "id		INTEGER			PRIMARY KEY ," 	// 在SQLite中设置为Integer、PRIMARY KEY则ID自动增长
				+ "name 	VARCHAR(50) 	NOT NULL ,"
				+ "birthday DATE NOT 		NULL" + ")";
		db.execSQL(sql) ;	// 执行SQL
		System.out.println("****************** 创建:onCreate()。");
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		String sql = "DROP TABLE IF EXISTS " + TABLENAME ;
		db.execSQL(sql) ;
		System.out.println("****************** 更新:onUpgrade()。");
		this.onCreate(db) ;
	}

}

 之前我们存入的数据早已写好,存入大概50多数据,存入数据方式参见前面几章

实现效果如下:



 



 

是不是对自己不断写入数据感到厌烦,不慌,接下来课我们实现一个程序去盗取人家的手机联系人,以及通话记录,看看你的他(她)有没有背着你做什么,当然,首先你要偷偷在他的手机安上这个东西。

猜你喜欢

转载自429899791.iteye.com/blog/2205307