【数据存储】SQLite数据库存储(5) 使用ListView滑动分页

要想实现这种滚动刷新操作,需实现一个滚动监听接口OnScrollListener的事件支持。

范例:SQLiteProject(滚动事件监听)

定义数据查询类 ----- MytabCursor.java

 

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 ;
    }
}
View Code

 

 

 

<?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> 
View Code

 

定义ListView显示的表格布局管理 ----- tab_info.xml

<?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>
View Code

定义Activity程序,进行分页显示 ----- MySQLiteDemo.java

 

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 ;    
View Code

 

 

 

    @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); 
    }
View Code

当currentPage=pageSize时,不再从数据表中读取记录。

 

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() ;    
            }
        }
    }
View Code

 

// 读取全部的数据
    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) ;
    }
View Code

主要功能是从表中读取数据,并且将这些数据设置到ListView进行显示,由于程序最后使用一个“加载中...”提示信息,所以使用addFooterView()将提示信息追加到了列表中。需注意的是,addFooterView()一定要在setAdapter()之前调用,否则会出错。

// 增加数据
    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() ;    
    }
View Code

 用户每次读取新数据时,都要向已有的List集合追加,而当List集合的内容改变之后,就可以通过SimpleAdapter类的notifyDataSetChanged()通知ListView集合数据已经改变,需重新加载显示。

 

 

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() ;
    }
}
View Code

 

 

 

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) ;
    }
}
View Code

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

原文地址:https://www.cnblogs.com/androidsj/p/3129479.html