网页上经常有分页表格的出现,同样的在Android上也可以实现。Android本身并没有直接提供表格这个控件,一般可以用GridView来实现比较简单,但是每个数据显示的长宽会一样。当然,也可以用ListView来实现,这个灵活定义每个数据显示的长宽。还有一种,是采用布局TableLayout来实现等等。这里用GridView,来实现一个。下载路径:http://download.csdn.net/source/3275713
它有几个特点:
1、实现分页;
2、简便的翻页按钮设置;
3、点击顶部字段名称会改变排序方式;
4、使用方便,只需几个参数。
(一)截图:
(二)关键部分:
1、视图架构:
该分页视图控件,由三部分组成:顶部:字段视图:gv_titles,主体:数据视图:gv_body,底部:分页按钮视图:bottomlayout。
2、SQl分页查询语句:
//查询语句 sql += " Limit " + TableRowCount + " Offset " + stratIndex;
3、排序方式的改变
String sql = "select * from (" + SimpleTable.this.sql + " Limit " + TableRowCount + " Offset " + pageID * TableRowCount + ") tempTable order by " + items[arg2][0] ; if(isDesc[arg2]) { sql += " asc "; isDesc[arg2] = false; }else { sql += " desc "; isDesc[arg2] = true; } Log.e("sql", sql); toPage(0, sql); } });
(三)代码:
1、数据项布局文件:items.xml
<?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>
2、Activity类:PaginatingTable
package com.myandroid.test; import java.util.HashMap; import java.util.Map; import android.app.Activity; import android.os.Bundle; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.widget.LinearLayout; public class PaginatingTable extends Activity { private LinearLayout linearLayout; private SimpleTable simpleTable; private String[][] items; private String sql; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); linearLayout = (LinearLayout)findViewById(R.id.linearLayout); //要查询的字段和对应显示的名称 items = new String[][]{ {"id", "序列"}, {"name", "姓名"}, {"time", "登陆时间"}, }; //插入一些数据测试用 SQLiteUtility.insertSomething(this); //查询语句 String sql = "select * from myTable"; //创建分页表格视图,只需要传入几个参数 SimpleTable simpleTable = new SimpleTable(this, items, sql, 7); linearLayout.addView(simpleTable); // addContentView(simpleTable, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, // ViewGroup.LayoutParams.WRAP_CONTENT)); } }
3、分页表格类:SimpleTable
package com.myandroid.test; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import android.content.Context; import android.database.Cursor; import android.graphics.Color; import android.graphics.Shader.TileMode; import android.graphics.Typeface; import android.util.Log; import android.view.Gravity; import android.view.View; import android.view.ViewGroup.LayoutParams; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.GridView; import android.widget.LinearLayout; import android.widget.SimpleAdapter; import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; import android.view.View.OnClickListener; public class SimpleTable extends LinearLayout implements OnClickListener, OnItemSelectedListener, OnItemClickListener{ private Context context; //上下文 private GridView gv_titles; //字段视图 private GridView gv_body; //数据视图 private LinearLayout bottomLayout; //视图底部布局 private Button bt_next, bt_pre, bt_first, bt_last; //按钮:下一页、上一页、首页、尾页 private TextView tv_page, tv_count; private Spinner sp_page; //页码下拉框 private String[][] items; //[字段][显示的名称] private String sql; //查询语句 private SimpleAdapter titlesAdatper; //字段视图适配器 private SimpleAdapter datasAdatper; //数据视图适配去 private int TableRowCount; //每页显示条数 private int pageID; //当前页码 private int TotalCount; //总记录条数 private int pageCount; //总页数 private String TableName; //表名和查询条件 private String[] fields; //字段名称 private boolean[] isDesc; //排序方式标记:false-递增排序,true-递减排序 private ArrayList<HashMap<String, String>> dataList; //数据集合 public SimpleTable(Context context) { super(context); this.context = context; } /** * 表格视图 * @param context 上下文 * @param items 字段名和对应显示名称 * @param sql SQl查询语句 * @param displayNum 每页的最大记录数 */ public SimpleTable(Context context, String[][] items, String sql, int TableRowCount) { super(context); this.context = context; this.items = items; this.sql = sql.replace(";", ""); this.TableRowCount = TableRowCount; //排序方式标记:false-递增排序,true-递减排序 isDesc = new boolean[items.length]; //当前页码 pageID = 0; //表名称和查询条件 TableName = sql.toLowerCase().substring(sql.toLowerCase().indexOf(" from ")+5, sql.length()).trim(); //记录总数 TotalCount = SQLiteUtility.getCount(context, "select count(*) from " + TableName); //总页码 pageCount = TotalCount%TableRowCount==0? TotalCount/TableRowCount-1 : TotalCount/TableRowCount; //字段名称 fields = new String[items.length]; for (int i = 0; i < items.length; i++) { fields[i] = items[i][0]; } setField(); //字段视图 setBody(); //数据视图 setBottomLayout(); //底部视图 setOrientation(LinearLayout.VERTICAL); addView(gv_titles); //添加视图 addView(gv_body); addView(bottomLayout); } /** * 设置字段视图 */ private void setField() { gv_titles = new GridView(context); gv_titles.setNumColumns(items.length); //字段标题 ArrayList<HashMap<String, String>> titles = new ArrayList<HashMap<String, String>>(); for(int i = 0; i < items.length; i++) { HashMap<String, String> map = new HashMap<String, String>(); map.put("title", items[i][1]); titles.add(map); } titlesAdatper = new SimpleAdapter(context, titles, R.layout.items, new String[]{"title"}, new int[] {R.id.ItemText}); gv_titles.setAdapter(titlesAdatper); //点击字段标题,改变排序方式 gv_titles.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { String sql = "select * from (" + SimpleTable.this.sql + " Limit " + TableRowCount + " Offset " + pageID * TableRowCount + ") tempTable order by " + items[arg2][0] ; if(isDesc[arg2]) { sql += " asc "; isDesc[arg2] = false; }else { sql += " desc "; isDesc[arg2] = true; } Log.e("sql", sql); toPage(0, sql); } }); } /** * 设置表格数据视图 */ private void setBody() { gv_body = new GridView(context); gv_body.setNumColumns(items.length); toPage(0, this.sql); //转到第一页 gv_body.setOnItemClickListener(this); //点击数据事件 } /** * 设置底部翻页视图, * 由如下组成:首页、上一页、下一页、尾页、页码选择、当期页码提示 */ private void setBottomLayout() { //底部容器 bottomLayout = new LinearLayout(context); bottomLayout.setOrientation(LinearLayout.HORIZONTAL); bottomLayout.setLayoutParams(new LayoutParams( LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); //翻页按钮 bt_pre = new Button(context); //上一页 bt_next = new Button(context); //下一页 bt_first = new Button(context); //首页 bt_last = new Button(context); //尾页 sp_page = new Spinner(context); //页码 tv_page = new TextView(context);//页码 //设置文本 bt_pre.setText("上一页"); bt_next.setText("下一页"); bt_first.setText("首页"); bt_last.setText("尾页"); tv_page.setText("页码:"); //设置页码下拉框选项 List<Integer> list = new ArrayList<Integer>(); for(int i = 0; i <= pageCount; i++) { list.add(i); } ArrayAdapter<Integer> pageAdapter = new ArrayAdapter<Integer>(context, android.R.layout.simple_spinner_item, list); sp_page.setAdapter(pageAdapter); //设置事件 sp_page.setOnItemSelectedListener(this); //设置下拉框事件 bt_first.setOnClickListener(this); bt_pre.setOnClickListener(this); bt_last.setOnClickListener(this); bt_next.setOnClickListener(this); //设置文本大小 bt_first.setTextSize(12); bt_pre.setTextSize(12); bt_last.setTextSize(12); bt_next.setTextSize(12); tv_page.setTextSize(12); //添加到底部容器 bottomLayout.addView(bt_first); bottomLayout.addView(bt_pre); bottomLayout.addView(bt_next); bottomLayout.addView(bt_last); bottomLayout.addView(tv_page); bottomLayout.addView(sp_page); } //设置显示大小 public void setSize(View v) { v.setLayoutParams(new android.view.ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); } /** * 翻页点击事件 */ @Override public void onClick(View v) { if(v == bt_first) { //第一页 pageID = 0; }else if(v == bt_last) { //最后一页 if(pageCount == 0) { return; } pageID = pageCount; }else if(v == bt_next) { //下一页 if(pageID < pageCount) { ++pageID; } else { return; } }else if(v == bt_pre) { //上一页 if(pageID <= 0){ return; }else { --pageID; } } sp_page.setSelection(pageID); } /** * 页码下拉框选择事件 */ @Override public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) { pageID = arg2; Log.e("onItemSelected:", "selected"); toPage(pageID * TableRowCount, this.sql); } @Override public void onNothingSelected(AdapterView<?> arg0) { // TODO Auto-generated method stub } /** * 跳转页面 * @param stratIndex 开始页码 * @param sql 查询语句 */ public void toPage(int stratIndex, String sql) { //查询语句 sql += " Limit " + TableRowCount + " Offset " + stratIndex; //获取查询结果集合 dataList = SQLiteUtility.query2(context, sql, fields); //设置适配器 SimpleAdapter simpleAdapter = new SimpleAdapter(context, dataList, R.layout.items, new String[]{"item"}, new int[] {R.id.ItemText}); gv_body.setAdapter(simpleAdapter); //重新添加适配器 } /** * 数据项点击事件 */ @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { Toast.makeText(context, ((HashMap<String, String>)dataList.get(arg2)).get("item"), Toast.LENGTH_SHORT).show(); } }
4、SQLite操作类:SQLiteUtility
package com.myandroid.test; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import android.app.ActivityGroup; import android.app.AlertDialog; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.util.Log; import android.widget.Toast; import android.database.Cursor; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; public class SQLiteUtility{ private static final int MODE_PRIVATE = 0x0; private static final String DATABASE = "myDB2"; private static SQLiteDatabase db; /** * 插入一些数据 */ public static void insertSomething(Context context) { Cursor cursor; int count = 0; String sql = "CREATE TABLE myTable (id int not null, " + "name text not null," + "time text not null );"; SimpleDateFormat bartDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH:mm"); Date date = new Date(); try { db = context.openOrCreateDatabase(DATABASE, MODE_PRIVATE, null); String sqlCheckExsit = "select count(*) as c from Sqlite_master where type ='table' and name ='myTable' "; cursor = db.rawQuery(sqlCheckExsit, null); if(cursor.moveToNext()){ count = cursor.getInt(0); if(count <= 0){ db.execSQL(sql); }else { db.execSQL("drop table myTable"); db.execSQL(sql); } } for(int i = 0; i <30; i++) { String insertSql = "insert into myTable (" + "id, name, time) values('" + i + "', 'admin','" + bartDateFormat.format(date) + "');"; db.execSQL(insertSql); } Log.e("insertSql", "ok"); }finally { db.close(); } } /** * 查询 * @param context 上下文 * @param sql SQl查询语句 * @param fields 字段名集合 * @return 查询结果集 List<String>类型 */ public static List<String> query(Context context, String sql, String[] fields) { List<String> dataList = new ArrayList<String>(); Cursor cursor; try { db = context.openOrCreateDatabase(DATABASE, MODE_PRIVATE, null); cursor = db.rawQuery(sql, null); if (cursor != null) { while (cursor.moveToNext()) { for (int i = 0; i < fields.length; i++) { String temp = cursor.getString(cursor .getColumnIndex(fields[i])); dataList.add(temp); } } } }catch(Exception e) { new AlertDialog.Builder(context) .setIcon(android.R.drawable.ic_dialog_alert) .setTitle("数据库连接错误:") .setMessage("数据访问异常。") .show(); } finally { db.close(); } return dataList; } /** * 数据记录总条数 * @param context 上下文 * @param sql SQL查询语句 * @return 记录条数 */ public static int getCount(Context context, String sql) { int totalCounty = 0; try { db = context.openOrCreateDatabase(DATABASE, MODE_PRIVATE, null); Cursor cursor = db.rawQuery(sql, null); cursor.moveToFirst(); totalCounty = cursor.getInt(0); } catch (Exception e) { new AlertDialog.Builder(context) .setIcon(android.R.drawable.ic_dialog_alert) .setTitle("数据库连接错误:").setMessage("数据访问异常。").show(); } finally { db.close(); } return totalCounty; } /** * 查询 * @param context 上下文 * @param sql SQl查询语句 * @param fields 字段名集合 * @return 查询结果集 ArrayList<HashMap<String,String>>类型 */ public static ArrayList<HashMap<String,String>> query2(Context context, String sql, String[] fields) { ArrayList<HashMap<String, String>> dataList = new ArrayList<HashMap<String, String>>(); Cursor cursor; //游标 try{ db = context.openOrCreateDatabase(DATABASE, MODE_PRIVATE, null); //连接数据库 cursor = db.rawQuery(sql, null); //获取数据集游标 if (cursor != null) { while (cursor.moveToNext()) { //游标递增,访问数据集 for (int i = 0; i < fields.length; i++) { String temp = cursor.getString(cursor //获取对应数据项 .getColumnIndex(fields[i])); HashMap<String, String> map = new HashMap<String, String>(); map.put("item", temp); dataList.add(map); } } } }catch(Exception e) { new AlertDialog.Builder(context) .setIcon(android.R.drawable.ic_dialog_alert) .setTitle("数据库连接错误:") .setMessage("数据访问异常。") .show(); }finally { cursor = null; db.close(); } return dataList; } }