HardBirch

Android提高第九篇之SQLite分页表格

时间:10-11-18 栏目:安卓入门与提高 作者:张飞不张,文采横飞 评论:55 点击: 24,761 次

       上次讲的Android上的《SQLite分页读取》,只用文本框显示数据而已,这次就讲得更加深入些,实现并封装一个SQL分页表格控件,不仅支持分页还是以表格的形式展示数据。先来看看本文程序运行的动画:

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

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

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

2.支持分页;

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

本文程序代码较多,可以到这里下载整个工程的源码:http://www.rayfile.com/files/72e78b68-f2e5-11df-8469-0015c55db73d/

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














main.xml的代码如下:













演示程序testSQLite.java的源码:






















@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的源码:
















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<HashMap<String, String>>();
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<HashMap<String, String>>();
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<String, String> map = new HashMap<String, String>();
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<colCount;ii++)//定位到一条数据中的每个字段
{
HashMap<String, String> map = new HashMap<String, String>();
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<String, String> map = new HashMap<String, String>();
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提高第九篇之SQLite分页表格

Android提高第九篇之SQLite分页表格:目前有55 条留言

  1. 0楼
    kf156:

    [e01]来了来了

    2010-11-18 16:17 [回复]
  2. 0楼
    kazeik:

    [e01]太牛了.

    2010-11-18 16:21 [回复]
  3. [e01][e01][e01][e01][e01]
    GV。。。。

    2010-11-18 16:26 [回复]
  4. 果然不是吹的。。。

    2010-11-18 16:27 [回复]
  5. 继续[e01] [e10]

    2010-11-18 16:29 [回复]
  6. 0楼
    hmc1985:

    [e01]

    2010-11-18 16:31 [回复]
  7. 0楼
    yangc_83:

    [e03]

    2010-11-18 16:37 [回复]
  8. [e01]

    2010-11-18 16:57 [回复]
  9. 0楼
    CODER_TAL:

    [e03]

    2010-11-18 23:44 [回复]
  10. 0楼
    super005:

    这分页不错阿。

    像sqlite的客服端。[e04][e03]

    2010-11-19 10:07 [回复]
  11. 0楼
    leejh528:

    [e01]

    2010-11-19 21:17 [回复]
  12. 0楼
    cll007:

    收藏,谢谢

    2010-11-20 17:51 [回复]
  13. 0楼
    liukeyuJ:

    楼主,好人

    2010-11-21 09:58 [回复]
  14. 0楼
    xuyan87101:

    [e01][e03]

    2010-11-22 11:24 [回复]
  15. 0楼
    JParadox:

    效果不错,[e01]

    2010-11-22 20:12 [回复]
  16. [e01]

    2010-11-22 20:18 [回复]
  17. 0楼
    nbdekang:

    谢谢!!

    2010-11-22 22:00 [回复]
  18. 0楼
    jinfei95:

    太好了,强烈支持!![e03]

    2010-11-23 12:41 [回复]
  19. 0楼
    boydemeng:

    [e01]

    2010-11-24 00:32 [回复]
  20. 0楼
    dreamid:

    [e04][e05][e04][e01]

    2010-11-24 08:40 [回复]
  21. [e01]

    2010-11-24 17:17 [回复]
  22. 0楼
    wqxstar:

    [e03]博主威武

    2010-11-30 09:09 [回复]
  23. 0楼
    mu399:

    [e01]很有营养

    2010-12-03 16:39 [回复]
  24. 0楼
    wuguo_:

    [e01][e03]强大!

    2010-12-29 11:02 [回复]
  25. [e01]偶像啊偶像

    2011-01-17 15:22 [回复]
  26. 0楼
    pxb7789606:

    张老师 学习您的程序 并做了部分修改 终于完成了工作… 但是后续想实现这样的功能却怎么调试不出来.请老师指教:

    问题: 希望显示数据的表格首行能够自动适应字段大小… 表格整体可以实现水平滚动.不要那个省略号的出现

    2011-02-15 13:35 [回复]
  27. 0楼
    asewq:

    [e01][e06][e10]
    多谢lz给出这么好的代码例子

    2011-03-22 17:24 [回复]
  28. 0楼
    kongyanmin:

    同上面一样的问题,望高手解答一下

    2011-04-05 17:35 [回复]
  29. [e10]

    2011-05-21 11:07 [回复]
  30. 0楼
    hellogv:

    回复 pxb7789606:
    文中已经说得很清楚了,GridView的缺点就是每个格单元的大小是一样的,不能做到有些大有些小,只能一起大一起小。。。

    2011-05-21 11:14 [回复]
  31. [e01]

    2011-06-21 11:14 [回复]
  32. 0楼
    hwq_00001:

    时常看lz帖子,感谢楼主的共享精神。。。

    2011-07-12 13:11 [回复]
  33. 2011-08-24 17:00 [回复]
  34. 手机上好象没有用到这么复杂的应用啊

    2011-08-24 17:02 [回复]
  35. 楼主。。辛苦了,我想问一下,如何我建好数据库并存储好数据后,更换测试的AVD,使得数据仍然显示?

    2011-10-13 06:17 [回复]
  36. 想问博主一个问题,如果数据库中的数据更多,要分很多页,如何实现类似于
    1 2 3 …… 尾页
    的效果呢?

    2011-11-24 15:55 [回复]
  37. 0楼
    hellogv:

    [reply]headmaster123456[/reply]
    不能用省略号,建议用“更多”按钮,弹出框选分页

    2011-11-24 23:39 [回复]
  38. 0楼
    vincent_20:

    很好很强大

    2011-12-07 16:17 [回复]
  39. 0楼
    cqc588677:

    能发源代码给我啊?258878479@qq.com 谢谢啦

    2012-03-07 10:57 [回复]
  40. 0楼
    cqc588677:

    这是我想要的代码实现功能,太感谢老师您啦!。。呵呵

    2012-03-07 10:57 [回复]
  41. 0楼
    acm365:

    评论给积分吗?不管怎样,我顶了

    2012-03-23 12:49 [回复]
  42. 好多哦 我也来顶一下

    2012-04-06 11:41 [回复]
  43. 0楼
    mmcq_:

    好好呀、、我正好能用、、谢谢谢谢、谢谢谢谢谢、谢谢谢谢谢、谢谢谢谢谢、谢谢谢谢谢、谢谢谢谢谢、谢谢谢谢谢、谢谢谢谢谢、谢谢谢谢谢、谢谢谢谢谢、谢谢谢谢谢、谢谢谢谢谢、谢谢谢谢谢、谢谢谢谢谢、谢谢谢谢谢、谢谢

    2012-04-11 10:14 [回复]
  44. 0楼
    wangzsyt:

    2012-04-12 17:56 [回复]
  45. 0楼
    xumy888:

    楼主,能不能对表格里面的数据进行编辑和保存呢?

    2012-05-01 21:03 [回复]
  46. 0楼
    hellogv:

    [reply]xumy888[/reply]
    这个要另外实现

    2012-05-02 14:00 [回复]
  47. 神级的写法,很强,受益匪浅。。。

    2012-05-03 10:19 [回复]
  48. 不错,学习学习

    2012-05-24 17:15 [回复]
  49. 0楼
    qi19900808:

    楼主 你的ItemImage从哪来的啊,谢谢了

    2012-06-02 22:09 [回复]
  50. 0楼
    hellogv:

    [reply]qi19900808[/reply]
    <TextView android:layout_below="@+id/ItemImage" android:text="TextView01"

    2012-06-04 09:15 [回复]
  51. 0楼
    qi19900808:

    android:layout_below="@+id/ItemImage"这个的意思不是android:id="@+id/ItemText"在ItemImage的下面么?那么ItemImage这个控件又在哪里呢?[reply]hellogv[/reply]

    2012-06-11 12:06 [回复]
  52. java.lang.IllegalStateException: database not open
    android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1723)

    出现以上错误,小弟在网上查了一下原因:好像是说数据库开启之后没关闭的原因,但是我试了重启以后还是这样?LZ能不能解释一下。谢谢!!!

    2012-07-02 19:52 [回复]
  53. 0楼
    gycxgycx:

    还有一个问题关闭数据库之后再创建,插入的数据是跟在上一次之后的,比如第一次插一组数据,第二次就是从id为16开始。
    刚发现了,上一个问题如果选择最后一页,下面的那一行分页还是有,但如果选别的页就没有了……

    2012-07-17 13:22 [回复]
  54. 0楼
    gycxgycx:

    奇怪了,刚尝试了下把屏幕竖起来就有了,但是屏幕变换就要重新创建数据库和插入数据……

    2012-07-17 13:46 [回复]
  55. 0楼
    a_xiaozhen:

    数据库的操作怎么使用批量!

    2012-08-21 11:29 [回复]

发表评论


QQ群互动

Linux系统与内核学习群:194051772

WP建站技术学习交流群:194062106

魔豆之路QR

魔豆的Linux内核之路

魔豆的Linux内核之路

优秀工程师当看优秀书籍

优秀程序员,要看优秀书!

赞助商广告

友荐云推荐