snailbing 2015-04-23
在对数据库读取中,分页滑动是十分重要的,例如你浏览空间时,往下拖动有时就会出现正在加载中字样,这种是正在像服务器数据库中读取数据现象,而且规定了每页只显示多少数据,有时网速不好还要加载很长时间
如图:
我们今天要做的就是要把之前学的数据库结合起来再加上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多数据,存入数据方式参见前面几章
实现效果如下:
是不是对自己不断写入数据感到厌烦,不慌,接下来课我们实现一个程序去盗取人家的手机联系人,以及通话记录,看看你的他(她)有没有背着你做什么,当然,首先你要偷偷在他的手机安上这个东西。