Android提高之SQLite分頁(yè)表格實(shí)現(xiàn)方法
繼前一篇文章講到Android上的SQLite分頁(yè)讀取,其功能只是用文本框顯示數(shù)據(jù)而已。本文就講得更加深入些,實(shí)現(xiàn)并封裝一個(gè)SQL分頁(yè)表格控件,不僅支持分頁(yè)還是以表格的形式展示數(shù)據(jù)。
先來(lái)看看本文程序運(yùn)行的動(dòng)畫(huà)如下圖所示:
這個(gè)SQL分頁(yè)表格控件主要分為“表格區(qū)”和“分頁(yè)欄”這兩部分,這兩部分都是基于GridView實(shí)現(xiàn)的。網(wǎng)上介紹Android上實(shí)現(xiàn)表格的DEMO一般都用ListView。ListView與GridView對(duì)比,ListView最大的優(yōu)勢(shì)是格單元的大小可以自定義,可以某單元長(zhǎng)某單元短,但是難于實(shí)現(xiàn)自適應(yīng)數(shù)據(jù)表的結(jié)構(gòu);而GridView最大的優(yōu)勢(shì)就是自適應(yīng)數(shù)據(jù)表的結(jié)構(gòu),但是格單元統(tǒng)一大小。對(duì)于數(shù)據(jù)表結(jié)構(gòu)多變的情況,建議使用GridView實(shí)現(xiàn)表格。
本文實(shí)現(xiàn)的SQL分頁(yè)表格控件有以下特點(diǎn):
1.自適應(yīng)數(shù)據(jù)表結(jié)構(gòu),但是格單元統(tǒng)一大小;
2.支持分頁(yè);
3.“表格區(qū)”有按鍵事件回調(diào)處理,“分頁(yè)欄”有分頁(yè)切換事件回調(diào)處理。
本文程序代碼較多,可以到這里下載整個(gè)工程的源碼:http://xiazai.jb51.net/201408/yuanma/testSQLite(jb51.bet).rar
items.xml的代碼如下,它是“表格區(qū)”和“分頁(yè)欄”的格單元實(shí)現(xiàn):
<?xml version="1.0" encoding="utf-8"?> <LinearLayout android:id="@+id/LinearLayout01" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:background="#555555" android:layout_height="wrap_content"> <TextView android:layout_below="@+id/ItemImage" android:text="TextView01" 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"> </TextView> </LinearLayout>
main.xml的代碼如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/MainLinearLayout"> <Button android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/btnCreateDB" android:text="創(chuàng)建數(shù)據(jù)庫(kù)"></Button> <Button android:layout_height="wrap_content" android:layout_width="fill_parent" android:text="插入一串實(shí)驗(yàn)數(shù)據(jù)" android:id="@+id/btnInsertRec"></Button> <Button android:layout_height="wrap_content" android:id="@+id/btnClose" android:text="關(guān)閉數(shù)據(jù)庫(kù)" android:layout_width="fill_parent"></Button> </LinearLayout>
演示程序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;//添加記錄時(shí)的id累加標(biāo)記,必須全局 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);//設(shè)置每個(gè)分頁(yè)的ROW總數(shù) 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)+ " 當(dāng)前第"+String.valueOf(pageID)+"頁(yè)"; 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(); } } } /** * 在內(nèi)存創(chuàng)建數(shù)據(jù)庫(kù)和數(shù)據(jù)表 */ void CreateDB() { // 在內(nèi)存創(chuàng)建數(shù)據(jù)庫(kù) db = SQLiteDatabase.create(null); Log.e("DB Path", db.getPath()); String amount = String.valueOf(databaseList().length); Log.e("DB amount", amount); // 創(chuàng)建數(shù)據(jù)表 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條數(shù)據(jù) */ 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) { } } } }
分頁(yè)表格控件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<HashMap<String, String>> srcPageID,srcTable;// 數(shù)據(jù)源 protected int TableRowCount=10;//分頁(yè)時(shí),每頁(yè)的Row總數(shù) protected int TableColCount=0;//每頁(yè)col的數(shù)量 protected SQLiteDatabase db; protected String rawSQL=""; protected Cursor curTable;//分頁(yè)時(shí)使用的Cursor protected OnTableClickListener clickListener;//整個(gè)分頁(yè)控件被點(diǎn)擊時(shí)的回調(diào)函數(shù) protected OnPageSwitchListener switchListener;//分頁(yè)切換時(shí)的回調(diào)函數(shù) public GVTable(Context context) { super(context); this.setOrientation(VERTICAL);//垂直 //---------------------------------------- gvTable=new GridView(context); addView(gvTable, new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));//寬長(zhǎng)式樣 srcTable = new ArrayList<HashMap<String, String>>(); saTable = new SimpleAdapter(context, srcTable,// 數(shù)據(jù)來(lái)源 R.layout.items,//XML實(shí)現(xiàn) new String[] { "ItemText" },// 動(dòng)態(tài)數(shù)組與ImageItem對(duì)應(yīng)的子項(xiàng) 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;//標(biāo)題欄的不算 int x=arg2 % curTable.getColumnCount(); if (clickListener != null//分頁(yè)數(shù)據(jù)被點(diǎn)擊 && y!=-1) {//點(diǎn)中的不是標(biāo)題欄時(shí) clickListener.onTableClickListener(x,y,curTable); } } }); //---------------------------------------- gvPage=new GridView(context); gvPage.setColumnWidth(40);//設(shè)置每個(gè)分頁(yè)按鈕的寬度 gvPage.setNumColumns(GridView.AUTO_FIT);//分頁(yè)按鈕數(shù)量自動(dòng)設(shè)置 addView(gvPage, new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));//寬長(zhǎng)式樣 srcPageID = new ArrayList<HashMap<String, String>>(); saPageID = new SimpleAdapter(context, srcPageID,// 數(shù)據(jù)來(lái)源 R.layout.items,//XML實(shí)現(xiàn) new String[] { "ItemText" },// 動(dòng)態(tài)數(shù)組與ImageItem對(duì)應(yīng)的子項(xiàng) 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);//根據(jù)所選分頁(yè)讀取對(duì)應(yīng)的數(shù)據(jù) if(switchListener!=null){//分頁(yè)切換時(shí) switchListener.onPageSwitchListener(arg2,srcPageID.size()); } } }); } /** * 清除所有數(shù)據(jù) */ public void gvRemoveAll() { if(this.curTable!=null) curTable.close(); srcTable.clear(); saTable.notifyDataSetChanged(); srcPageID.clear(); saPageID.notifyDataSetChanged(); } /** * 讀取指定ID的分頁(yè)數(shù)據(jù),返回當(dāng)前頁(yè)的總數(shù)據(jù) * SQL:Select * From TABLE_NAME Limit 9 Offset 10; * 表示從TABLE_NAME表獲取數(shù)據(jù),跳過(guò)10行,取9行 * @param pageID 指定的分頁(yè)ID */ protected void LoadTable(int pageID) { if(curTable!=null)//釋放上次的數(shù)據(jù) curTable.close(); String sql= rawSQL+" Limit "+String.valueOf(TableRowCount)+ " Offset " +String.valueOf(pageID*TableRowCount); curTable = db.rawQuery(sql, null); gvTable.setNumColumns(curTable.getColumnCount());//表現(xiàn)為表格的關(guān)鍵點(diǎn)! 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); } // 列舉出所有數(shù)據(jù) int recCount=curTable.getCount(); for (int i = 0; i < recCount; i++) {//定位到一條數(shù)據(jù) curTable.moveToPosition(i); for(int ii=0;ii<colCount;ii++)//定位到一條數(shù)據(jù)中的每個(gè)字段 { HashMap<String, String> map = new HashMap<String, String>(); map.put("ItemText", curTable.getString(ii)); srcTable.add(map); } } saTable.notifyDataSetChanged(); } /** * 設(shè)置表格的最多顯示的行數(shù) * @param row 表格的行數(shù) */ public void gvSetTableRowCount(int row) { TableRowCount=row; } /** * 取得表格的最大行數(shù) * @return 行數(shù) */ public int gvGetTableRowCount() { return TableRowCount; } /** * 取得當(dāng)前分頁(yè)的Cursor * @return 當(dāng)前分頁(yè)的Cursor */ public Cursor gvGetCurrentTable() { return curTable; } /** * 準(zhǔn)備分頁(yè)顯示數(shù)據(jù) * @param rawSQL sql語(yǔ)句 * @param db 數(shù)據(jù)庫(kù) */ public void gvReadyTable(String rawSQL,SQLiteDatabase db) { this.rawSQL=rawSQL; this.db=db; } /** * 刷新分頁(yè)欄,更新按鈕數(shù)量 * @param sql SQL語(yǔ)句 * @param db 數(shù)據(jù)庫(kù) */ public void gvUpdatePageBar(String sql,SQLiteDatabase db) { Cursor rec = db.rawQuery(sql, null); rec.moveToLast(); long recSize=rec.getLong(0);//取得總數(shù) rec.close(); int pageNum=(int)(recSize/TableRowCount) + 1;//取得分頁(yè)數(shù) 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(); } //--------------------------------------------------------- /** * 表格被點(diǎn)擊時(shí)的回調(diào)函數(shù) */ public void setTableOnClickListener(OnTableClickListener click) { this.clickListener = click; } public interface OnTableClickListener { public void onTableClickListener(int x,int y,Cursor c); } //--------------------------------------------------------- /** * 分頁(yè)欄被點(diǎn)擊時(shí)的回調(diào)函數(shù) */ public void setOnPageSwitchListener(OnPageSwitchListener pageSwitch) { this.switchListener = pageSwitch; } public interface OnPageSwitchListener { public void onPageSwitchListener(int pageID,int pageCount); } }
希望本文所述實(shí)例對(duì)于大家進(jìn)行Android項(xiàng)目開(kāi)發(fā)能起到參考借鑒作用。
- Android中實(shí)現(xiàn)多行、水平滾動(dòng)的分頁(yè)的Gridview實(shí)例源碼
- Android中RecyclerView實(shí)現(xiàn)分頁(yè)滾動(dòng)的方法詳解
- Android之ListView分頁(yè)加載數(shù)據(jù)功能實(shí)現(xiàn)代碼
- Android實(shí)現(xiàn)ListView分頁(yè)自動(dòng)加載數(shù)據(jù)的方法
- android實(shí)現(xiàn)listview分頁(yè)的方法
- Android Recyclerview實(shí)現(xiàn)水平分頁(yè)GridView效果示例
- Android實(shí)現(xiàn)簡(jiǎn)單的分頁(yè)效果
- Android開(kāi)發(fā)中滑動(dòng)分頁(yè)功能實(shí)例詳解
- Android端代碼量非常小的分頁(yè)加載庫(kù)
相關(guān)文章
Android布局(RelativeLayout、TableLayout等)使用方法
這篇文章主要介紹了Android布局使用方法及各種屬性介紹,包括RelativeLayout、TableLayout等,感興趣的朋友可以參考一下2016-03-03Android添加ButterKnife時(shí)報(bào)錯(cuò)Error:(2, 0) Cannot add extension wit
今天小編就為大家分享一篇關(guān)于Android添加ButterKnife時(shí)報(bào)錯(cuò)Error:(2, 0) Cannot add extension with name 'android'的解決辦法,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-12-12Android補(bǔ)間動(dòng)畫(huà)的實(shí)現(xiàn)示例
本文主要介紹了Android補(bǔ)間動(dòng)畫(huà)的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04android實(shí)現(xiàn)簡(jiǎn)單左滑刪除控件
這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)一個(gè)簡(jiǎn)單左滑刪除控件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08Android程序開(kāi)發(fā)如何處理圖像格式類及圖像轉(zhuǎn)換
這篇文章主要介紹了Android程序開(kāi)發(fā)如何處理圖像格式類及圖像轉(zhuǎn)換,需要的朋友可以參考下2015-07-07Android之使用Android-query框架開(kāi)發(fā)實(shí)戰(zhàn)(二)
這篇文章主要介紹了Android之使用Android-query框架開(kāi)發(fā)實(shí)戰(zhàn)(二)的相關(guān)資料,需要的朋友可以參考下2015-10-10一文教你如何使用Databinding寫(xiě)一個(gè)關(guān)注功能
這篇文章主要介紹了一文教你如何使用Databinding寫(xiě)一個(gè)關(guān)注功能,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-09