要想实现这种滚动刷新操作,需实现一个滚动监听接口OnScrollListener的事件支持。
范例:SQLiteProject(滚动事件监听)
定义数据查询类 ----- MytabCursor.java
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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; // 查询SQL String sql = "SELECT COUNT(id) FROM " + TABLENAME; 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) }; // 是设置参数 // 执行查询语句 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 ; } }
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
<?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显示的表格布局管理 ----- tab_info.xml
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
<?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>
定义Activity程序,进行分页显示 ----- MySQLiteDemo.java
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
import java.util.List; import java.util.Map; import android.app.Activity; import android.database.sqlite.SQLiteOpenHelper; import android.os.Bundle; import android.util.Log; import android.view.Gravity; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; import android.widget.LinearLayout; import android.widget.LinearLayout.LayoutParams; import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.TextView; 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 ; // 每页显示15条数据 private int lineSize = 15 ; // 保存全部记录数 private int allRecorders = 0 ; // 默认在一共只有1页 private int pageSize = 1 ; // 保存最后一项 private int lastItem = 0 ;
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
@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); }
当currentPage=pageSize时,不再从数据表中读取记录。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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() ; } } }
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// 读取全部的数据 private void showAllData(){ MySQLiteDemo.this.helper = new MyDatabaseHelper(MySQLiteDemo.this); // 实例化查询 // 取得SQLiteDatabase对象 MytabCursor cur = new MytabCursor( MySQLiteDemo.this.helper.getReadableDatabase()) ; // 取得全部记录数 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 }) ; // 布局管理中的id this.listView.setAdapter(this.simpleAdapter); // 设置滚动监听 this.listView.setOnScrollListener(new OnScrollListenerImpl()) ; // 追加组件 this.mylayout.addView(listView) ; }
主要功能是从表中读取数据,并且将这些数据设置到ListView进行显示,由于程序最后使用一个“加载中...”提示信息,所以使用addFooterView()将提示信息追加到了列表中。需注意的是,addFooterView()一定要在setAdapter()之前调用,否则会出错。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// 增加数据 private void appendData(){ // 实例化查询 MytabCursor cur = new MytabCursor( // 取得SQLiteDatabase对象 MySQLiteDemo.this.helper.getReadableDatabase()) ; List<Map<String, Object>> newData = cur.find(this.currentPage,this.lineSize); // 集合改变 this.all.addAll(newData) ; // 通知记录改变 this.simpleAdapter.notifyDataSetChanged() ; }
用户每次读取新数据时,都要向已有的List集合追加,而当List集合的内容改变之后,就可以通过SimpleAdapter类的notifyDataSetChanged()通知ListView集合数据已经改变,需重新加载显示。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
import android.content.ContentValues; import android.database.sqlite.SQLiteDatabase; public class MytabOperate { // 表示要操作的数据表名称 private static final String TABLENAME = "mytab"; // 数据库操作 private SQLiteDatabase db = null; public MytabOperate(SQLiteDatabase db) { this.db = db; } public void insert(String name,String birthday) { ContentValues cv = new ContentValues() ; cv.put("name", name) ; cv.put("birthday", birthday) ; this.db.insert(TABLENAME, null, cv) ; this.db.close() ; } public void update(int id, String name, String birthday) { ContentValues cv = new ContentValues() ; cv.put("name", name) ; cv.put("birthday", birthday) ; String whereClause = "id=?" ; String whereArgs[] = new String[]{String.valueOf(id)} ; this.db.update(TABLENAME, cv, whereClause, whereArgs) ; this.db.close() ; } public void delete(int id) { String whereClause = "id=?" ; String whereArgs[] = new String[]{String.valueOf(id)} ; this.db.delete(TABLENAME, whereClause, whereArgs) ; this.db.close() ; } }
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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" ; // 用户最关心的也肯定只是Context public MyDatabaseHelper(Context context) { super(context, DATABASENAME, null, DATABASERVERSION); } @Override public void onCreate(SQLiteDatabase db) { String sql = "CREATE TABLE " + TABLENAME + "(" + "id INTEGER PRIMARY KEY ," + "name VARCHAR(50) NOT NULL ," + "birthday DATE NOT NULL" + ")"; db.execSQL(sql) ; // 执行SQL } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { String sql = "DROP TABLE IF EXISTS " + TABLENAME ; db.execSQL(sql) ; this.onCreate(db) ; } }