android 表格分页,Android提高之SQLite分页表格实现方法

继前一篇文章讲到Android上的SQLite分页读取,其功能只是用文本框显示数据而已。本文就讲得更加深入些,实现并封装一个SQL分页表格控件,不仅支持分页还是以表格的形式展示数据。

先来看看本文程序运行的动画如下图所示:

c5486366d48972cb7f29095ea3b43c6c.gif

这个SQL分页表格控件主要分为“表格区”和“分页栏”这两部分,这两部分都是基于GridView实现的。网上介绍Android上实现表格的DEMO一般都用ListView。ListView与GridView对比,ListView最大的优势是格单元的大小可以自定义,可以某单元长某单元短,但是难于实现自适应数据表的结构;而GridView最大的优势就是自适应数据表的结构,但是格单元统一大小。对于数据表结构多变的情况,建议使用GridView实现表格。

本文实现的SQL分页表格控件有以下特点:

1.自适应数据表结构,但是格单元统一大小;

2.支持分页;

3.“表格区”有按键事件回调处理,“分页栏”有分页切换事件回调处理。

items.xml的代码如下,它是“表格区”和“分页栏”的格单元实现:

xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent" android:background="#555555"

android:layout_height="wrap_content">

android:id="@+id/ItemText" android:bufferType="normal"

android:singleLine="true" android:background="#000000"

android:layout_width="fill_parent" android:gravity="center"

android:layout_margin="1dip" android:layout_gravity="center"

android:layout_height="wrap_content">

main.xml的代码如下:

android:orientation="vertical" android:layout_width="fill_parent"

android:layout_height="fill_parent" android:id="@+id/MainLinearLayout">

android:layout_width="fill_parent" android:id="@+id/btnCreateDB"

android:text="创建数据库">

android:layout_width="fill_parent" android:text="插入一串实验数据" android:id="@+id/btnInsertRec">

android:text="关闭数据库" android:layout_width="fill_parent">

演示程序testSQLite.java的源码如下:

package com.testSQLite;

import android.app.Activity;

import android.database.Cursor;

import android.database.SQLException;

import android.database.sqlite.SQLiteDatabase;

import android.os.Bundle;

import android.util.Log;

import android.view.View;

import android.widget.Button;

import android.widget.LinearLayout;

import android.widget.Toast;

public class testSQLite extends Activity {

GVTable table;

Button btnCreateDB, btnInsert, btnClose;

SQLiteDatabase db;

int id;//添加记录时的id累加标记,必须全局

private static final String TABLE_NAME = "stu";

private static final String ID = "id";

private static final String NAME = "name";

private static final String PHONE = "phone";

private static final String ADDRESS = "address";

private static final String AGE = "age";

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

btnCreateDB = (Button) this.findViewById(R.id.btnCreateDB);

btnCreateDB.setOnClickListener(new ClickEvent());

btnInsert = (Button) this.findViewById(R.id.btnInsertRec);

btnInsert.setOnClickListener(new ClickEvent());

btnClose = (Button) this.findViewById(R.id.btnClose);

btnClose.setOnClickListener(new ClickEvent());

table=new GVTable(this);

table.gvSetTableRowCount(8);//设置每个分页的ROW总数

LinearLayout ly = (LinearLayout) findViewById(R.id.MainLinearLayout);

table.setTableOnClickListener(new GVTable.OnTableClickListener() {

@Override

public void onTableClickListener(int x,int y,Cursor c) {

c.moveToPosition(y);

String str=c.getString(x)+" 位置:("+String.valueOf(x)+","+String.valueOf(y)+")";

Toast.makeText(testSQLite.this, str, 1000).show();

}

});

table.setOnPageSwitchListener(new GVTable.OnPageSwitchListener() {

@Override

public void onPageSwitchListener(int pageID,int pageCount) {

String str="共有"+String.valueOf(pageCount)+

" 当前第"+String.valueOf(pageID)+"页";

Toast.makeText(testSQLite.this, str, 1000).show();

}

});

ly.addView(table);

}

class ClickEvent implements View.OnClickListener {

@Override

public void onClick(View v) {

if (v == btnCreateDB) {

CreateDB();

} else if (v == btnInsert) {

InsertRecord(16);//插入16条记录

table.gvUpdatePageBar("select count(*) from " + TABLE_NAME,db);

table.gvReadyTable("select * from " + TABLE_NAME,db);

}else if (v == btnClose) {

table.gvRemoveAll();

db.close();

}

}

}

/**

* 在内存创建数据库和数据表

*/

void CreateDB() {

// 在内存创建数据库

db = SQLiteDatabase.create(null);

Log.e("DB Path", db.getPath());

String amount = String.valueOf(databaseList().length);

Log.e("DB amount", amount);

// 创建数据表

String sql = "CREATE TABLE " + TABLE_NAME + " (" +

ID + " text not null, " + NAME + " text not null," +

ADDRESS + " text not null, " + PHONE + " text not null," +

AGE + " text not null "+");";

try {

db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);

db.execSQL(sql);

} catch (SQLException e) {}

}

/**

* 插入N条数据

*/

void InsertRecord(int n) {

int total = id + n;

for (; id < total; id++) {

String sql = "insert into " + TABLE_NAME + " (" +

ID + ", " + NAME+", " + ADDRESS+", " + PHONE+", "+AGE

+ ") values('" + String.valueOf(id) + "', 'man','address','123456789','18');";

try {

db.execSQL(sql);

} catch (SQLException e) {

}

}

}

}

分页表格控件GVTable.java的源码如下:

package com.testSQLite;

import java.util.ArrayList;

import java.util.HashMap;

import android.content.Context;

import android.database.Cursor;

import android.database.sqlite.SQLiteDatabase;

import android.view.View;

import android.widget.AdapterView;

import android.widget.GridView;

import android.widget.LinearLayout;

import android.widget.SimpleAdapter;

import android.widget.AdapterView.OnItemClickListener;

public class GVTable extends LinearLayout {

protected GridView gvTable,gvPage;

protected SimpleAdapter saPageID,saTable;// 适配器

protected ArrayList> srcPageID,srcTable;// 数据源

protected int TableRowCount=10;//分页时,每页的Row总数

protected int TableColCount=0;//每页col的数量

protected SQLiteDatabase db;

protected String rawSQL="";

protected Cursor curTable;//分页时使用的Cursor

protected OnTableClickListener clickListener;//整个分页控件被点击时的回调函数

protected OnPageSwitchListener switchListener;//分页切换时的回调函数

public GVTable(Context context) {

super(context);

this.setOrientation(VERTICAL);//垂直

//----------------------------------------

gvTable=new GridView(context);

addView(gvTable, new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,

LayoutParams.WRAP_CONTENT));//宽长式样

srcTable = new ArrayList>();

saTable = new SimpleAdapter(context,

srcTable,// 数据来源

R.layout.items,//XML实现

new String[] { "ItemText" },// 动态数组与ImageItem对应的子项

new int[] { R.id.ItemText });

// 添加并且显示

gvTable.setAdapter(saTable);

gvTable.setOnItemClickListener(new OnItemClickListener(){

@Override

public void onItemClick(AdapterView> arg0, View arg1, int arg2,

long arg3) {

int y=arg2/curTable.getColumnCount()-1;//标题栏的不算

int x=arg2 % curTable.getColumnCount();

if (clickListener != null//分页数据被点击

&& y!=-1) {//点中的不是标题栏时

clickListener.onTableClickListener(x,y,curTable);

}

}

});

//----------------------------------------

gvPage=new GridView(context);

gvPage.setColumnWidth(40);//设置每个分页按钮的宽度

gvPage.setNumColumns(GridView.AUTO_FIT);//分页按钮数量自动设置

addView(gvPage, new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,

LayoutParams.WRAP_CONTENT));//宽长式样

srcPageID = new ArrayList>();

saPageID = new SimpleAdapter(context,

srcPageID,// 数据来源

R.layout.items,//XML实现

new String[] { "ItemText" },// 动态数组与ImageItem对应的子项

new int[] { R.id.ItemText });

// 添加并且显示

gvPage.setAdapter(saPageID);

// 添加消息处理

gvPage.setOnItemClickListener(new OnItemClickListener(){

@Override

public void onItemClick(AdapterView> arg0, View arg1, int arg2,

long arg3) {

LoadTable(arg2);//根据所选分页读取对应的数据

if(switchListener!=null){//分页切换时

switchListener.onPageSwitchListener(arg2,srcPageID.size());

}

}

});

}

/**

* 清除所有数据

*/

public void gvRemoveAll()

{

if(this.curTable!=null)

curTable.close();

srcTable.clear();

saTable.notifyDataSetChanged();

srcPageID.clear();

saPageID.notifyDataSetChanged();

}

/**

* 读取指定ID的分页数据,返回当前页的总数据

* SQL:Select * From TABLE_NAME Limit 9 Offset 10;

* 表示从TABLE_NAME表获取数据,跳过10行,取9行

* @param pageID 指定的分页ID

*/

protected void LoadTable(int pageID)

{

if(curTable!=null)//释放上次的数据

curTable.close();

String sql= rawSQL+" Limit "+String.valueOf(TableRowCount)+ " Offset " +String.valueOf(pageID*TableRowCount);

curTable = db.rawQuery(sql, null);

gvTable.setNumColumns(curTable.getColumnCount());//表现为表格的关键点!

TableColCount=curTable.getColumnCount();

srcTable.clear();

// 取得字段名称

int colCount = curTable.getColumnCount();

for (int i = 0; i < colCount; i++) {

HashMap map = new HashMap();

map.put("ItemText", curTable.getColumnName(i));

srcTable.add(map);

}

// 列举出所有数据

int recCount=curTable.getCount();

for (int i = 0; i < recCount; i++) {//定位到一条数据

curTable.moveToPosition(i);

for(int ii=0;ii

{

HashMap map = new HashMap();

map.put("ItemText", curTable.getString(ii));

srcTable.add(map);

}

}

saTable.notifyDataSetChanged();

}

/**

* 设置表格的最多显示的行数

* @param row 表格的行数

*/

public void gvSetTableRowCount(int row)

{

TableRowCount=row;

}

/**

* 取得表格的最大行数

* @return 行数

*/

public int gvGetTableRowCount()

{

return TableRowCount;

}

/**

* 取得当前分页的Cursor

* @return 当前分页的Cursor

*/

public Cursor gvGetCurrentTable()

{

return curTable;

}

/**

* 准备分页显示数据

* @param rawSQL sql语句

* @param db 数据库

*/

public void gvReadyTable(String rawSQL,SQLiteDatabase db)

{

this.rawSQL=rawSQL;

this.db=db;

}

/**

* 刷新分页栏,更新按钮数量

* @param sql SQL语句

* @param db 数据库

*/

public void gvUpdatePageBar(String sql,SQLiteDatabase db)

{

Cursor rec = db.rawQuery(sql, null);

rec.moveToLast();

long recSize=rec.getLong(0);//取得总数

rec.close();

int pageNum=(int)(recSize/TableRowCount) + 1;//取得分页数

srcPageID.clear();

for (int i = 0; i < pageNum; i++) {

HashMap map = new HashMap();

map.put("ItemText", "No." + String.valueOf(i));// 添加图像资源的ID

srcPageID.add(map);

}

saPageID.notifyDataSetChanged();

}

//---------------------------------------------------------

/**

* 表格被点击时的回调函数

*/

public void setTableOnClickListener(OnTableClickListener click) {

this.clickListener = click;

}

public interface OnTableClickListener {

public void onTableClickListener(int x,int y,Cursor c);

}

//---------------------------------------------------------

/**

* 分页栏被点击时的回调函数

*/

public void setOnPageSwitchListener(OnPageSwitchListener pageSwitch) {

this.switchListener = pageSwitch;

}

public interface OnPageSwitchListener {

public void onPageSwitchListener(int pageID,int pageCount);

}

}

希望本文所述实例对于大家进行Android项目开发能起到参考借鉴作用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Studio 中创建 SQLite 数据库表格需要以下步骤: 1. 在项目的 `app` 目录下的 `java` 文件夹中创建一个新的 `DatabaseHelper` 类,继承自 `SQLiteOpenHelper` 类。 ```java public class DatabaseHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME = "mydatabase.db"; private static final int DATABASE_VERSION = 1; public DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { String CREATE_TABLE = "CREATE TABLE mytable (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER)"; db.execSQL(CREATE_TABLE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { String DROP_TABLE = "DROP TABLE IF EXISTS mytable"; db.execSQL(DROP_TABLE); onCreate(db); } } ``` 2. 在 `onCreate()` 方法中创建表格,这里创建了一个名为 `mytable` 的表格,包含三个字段:`id`、`name` 和 `age`。 ```java String CREATE_TABLE = "CREATE TABLE mytable (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER)"; db.execSQL(CREATE_TABLE); ``` 3. 在 `onUpgrade()` 方法中更新表格,这里先删除了旧的表格,再重新创建一个新的表格。 ```java String DROP_TABLE = "DROP TABLE IF EXISTS mytable"; db.execSQL(DROP_TABLE); onCreate(db); ``` 4. 在需要使用数据库的地方,创建一个 `DatabaseHelper` 对象,并获取一个可写的数据库实例。 ```java DatabaseHelper dbHelper = new DatabaseHelper(context); SQLiteDatabase db = dbHelper.getWritableDatabase(); ``` 5. 在获取到数据库实例后,就可以使用各种 SQL 语句对数据进行操作了,例如插入数据、查询数据、更新数据、删除数据等等。 ```java // 插入数据 ContentValues values = new ContentValues(); values.put("name", "Tom"); values.put("age", 20); db.insert("mytable", null, values); // 查询数据 Cursor cursor = db.query("mytable", null, null, null, null, null, null); while (cursor.moveToNext()) { int id = cursor.getInt(cursor.getColumnIndex("id")); String name = cursor.getString(cursor.getColumnIndex("name")); int age = cursor.getInt(cursor.getColumnIndex("age")); Log.d("TAG", "id: " + id + ", name: " + name + ", age: " + age); } // 更新数据 ContentValues values = new ContentValues(); values.put("age", 21); db.update("mytable", values, "name = ?", new String[]{"Tom"}); // 删除数据 db.delete("mytable", "age < ?", new String[]{"20"}); ``` 以上就是在 Android Studio 中创建 SQLite 数据库表格的基本步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值