六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 2862|回复: 3

很久没有写东西了,一来是因为项目紧,没有多少时间,...

[复制链接]
 楼主| 发表于 2012-10-9 00:44:41 | 显示全部楼层 |阅读模式
很久没有写东西了,一来是因为项目紧,没有多少时间,二来是因为最近越来越懒了。。。。  今天说说数据库的分页显示问题,都是些自己在项目中碰到的问题,写在这里,留作以后复习用。。。。
  所谓数据库的分页显示,必须先要有一个数据库,先创建一个数据库。我这里用的是继承SQLiteOpenHelper的方法。具体如下:
  1. *package com.android.database;

  2. import android.content.ContentValues;
  3. import android.content.Context;
  4. import android.database.sqlite.SQLiteDatabase;
  5. import android.database.sqlite.SQLiteOpenHelper;
  6. import android.provider.BaseColumns;
  7. /**
  8. *
  9. * @author shangzhenxiang
  10. * 创建数据库,继承SQLiteOpenHelper。
  11. *
  12. */
  13. public class DBHelper extends SQLiteOpenHelper {

  14. private static final String DATABASE_NAME = "database.db";
  15. private static final int DATABASE_VERSION = 1;
  16. private static final String TABLE_NAME = "database";
  17. public static final String FIELD_TITLE = "title";

  18. public DBHelper(Context context) {
  19. super(context, DATABASE_NAME, null, DATABASE_VERSION);
  20. }

  21. /**
  22. * 创建表,写一个创建表的sql语句,然后调用db.execSQL(sql);之后向表中添加几条数据。
  23. */
  24. @Override
  25. public void onCreate(SQLiteDatabase db) {
  26. String sql="Create table "+TABLE_NAME+"("+BaseColumns._ID+" integer primary key autoincrement,"
  27. + FIELD_TITLE + " text );";
  28. db.execSQL(sql);

  29. //初始化数据库
  30. initDatabase(db);
  31. }

  32. //向数据库的表中插入一些数据。
  33. private void initDatabase(SQLiteDatabase db) {
  34. ContentValues cv = new ContentValues();
  35. cv.put("title", "cctv1 news");
  36. db.insert(TABLE_NAME, null, cv);

  37. cv.clear();
  38. cv.put("title", "cctv2 news");
  39. db.insert(TABLE_NAME, null, cv);

  40. cv.clear();
  41. cv.put("title", "cctv3 news");
  42. db.insert(TABLE_NAME, null, cv);

  43. cv.clear();
  44. cv.put("title", "cctv4 news");
  45. db.insert(TABLE_NAME, null, cv);

  46. cv.clear();
  47. cv.put("title", "cctv5 news");
  48. db.insert(TABLE_NAME, null, cv);

  49. cv.clear();
  50. cv.put("title", "cctv6 news");
  51. db.insert(TABLE_NAME, null, cv);

  52. cv.clear();
  53. cv.put("title", "cctv7 news");
  54. db.insert(TABLE_NAME, null, cv);

  55. cv.clear();
  56. cv.put("title", "cctv8 news");
  57. db.insert(TABLE_NAME, null, cv);

  58. cv.clear();
  59. cv.put("title", "cctv9 news");
  60. db.insert(TABLE_NAME, null, cv);

  61. cv.clear();
  62. cv.put("title", "cctv10 news");
  63. db.insert(TABLE_NAME, null, cv);

  64. cv.clear();
  65. cv.put("news_title", "guangshui tv");
  66. db.insert(TABLE_NAME, null, cv);
  67. }

  68. //这里是用于更新数据库的。
  69. @Override
  70. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  71. String sql=" DROP TABLE IF EXISTS "+TABLE_NAME;
  72. db.execSQL(sql);
  73. onCreate(db);
  74. }
  75. }
复制代码
代码注释的比较清楚,数据库很简单,只有一个id 和 title键值,id是自动增长的,是系统自动的,在创建数据库的时候,我在里面加了9跳数据,用作测试用。  数据库写完了,那好,我们要测试一下,到底生成了数据库文件没有呢?
  这时我们要写一个测试程序,来生成数据库文件,这需要在 manifest文件中做一些处理,如下所示:
  1. package com.android.database;

  2. import android.test.AndroidTestCase;
  3. /**
  4. *
  5. * @author shangzhenxiang
  6. *
  7. */
  8. public class DBTest extends AndroidTestCase {
  9. public void testCreateRecordedDB() throws Exception {
  10. DBHelper recordedDbHelper = new DBHelper(this.getContext());
  11. /**
  12. * 当我们调用recordedDbHelper的getWritableDatabase()或getReadableDatabase()的时候,
  13. * 都会导致数据库的生成
  14. */
  15. recordedDbHelper.getWritableDatabase();
  16. // recordedDbHelper.getReadableDatabase();
  17. }
  18. }
复制代码
生成的数据库文件在哪里呢?  在data文件夹下的data文件夹中找到刚刚在manifest中的targetPackage:
  
  目标包中有个database的文件夹,里面就是生成的数据库文件,如下图:
  
  数据库完成了,我们需要写一个单独的类用来显示页数和每一页上的个数,如图所示:
  1. package com.android.domain;

  2. public class Model {

  3. /**
  4. * @author shangzhenxiang
  5. * index 用于显示页数
  6. * View_Count 用于每一页上显示的个数
  7. */
  8. private int index;
  9. private int View_Count;

  10. public Model(int index, int View_Count) {
  11. this.index = index;
  12. this.View_Count = View_Count;
  13. }

  14. public int getIndex() {
  15. return index;
  16. }

  17. public void setIndex(int index) {
  18. this.index = index;
  19. }

  20. public int getView_Count() {
  21. return View_Count;
  22. }

  23. public void setView_Count(int view_Count) {
  24. View_Count = view_Count;
  25. }


  26. }
复制代码
我们还需要一个服务来操作数据库,就是我们常说的业务逻辑层。  我们需要对数据库做什么操作,都可以写到这个类中:
  1. package com.android.service;

  2. import java.util.ArrayList;

  3. import android.content.Context;
  4. import android.database.Cursor;
  5. import android.database.sqlite.SQLiteDatabase;

  6. import com.android.database.DBHelper;
  7. /**
  8. *
  9. * @author shangzhenxiang
  10. *
  11. */
  12. public class DatabaseService {

  13. private Context mContext;
  14. private DBHelper dbHelper;

  15. public DatabaseService(Context context) {
  16. // TODO Auto-generated constructor stub
  17. mContext = context;
  18. dbHelper = new DBHelper(mContext);
  19. }

  20. //添加
  21. public void insert(String title) {
  22. SQLiteDatabase db = dbHelper.getWritableDatabase();
  23. String sql = "insert into database(title) values(?)";
  24. db.execSQL(sql, new String[]{title});
  25. }

  26. //删除
  27. public void delete(String title) {
  28. SQLiteDatabase db = dbHelper.getWritableDatabase();
  29. String sql = "delete from database where title = ?";
  30. db.execSQL(sql, new String[]{title});
  31. }

  32. //查找
  33. public ArrayList<String> find(int id) {
  34. SQLiteDatabase db = dbHelper.getWritableDatabase();
  35. String sql = "select * from database where _id = ? ";
  36. Cursor c = db.rawQuery(sql, new String[]{String.valueOf(id)});
  37. ArrayList<String> titles = new ArrayList<String>();
  38. if(c.moveToNext()) {
  39. String title =c.getString(c.getColumnIndexOrThrow(DBHelper.FIELD_TITLE));
  40. titles.add(title);
  41. return titles;
  42. }
  43. //不用忘记关闭Cursor。
  44. c.close();
  45. return null;
  46. }

  47. //更新
  48. public void upDate(int id, String title) {
  49. SQLiteDatabase db = dbHelper.getWritableDatabase();
  50. String sql = "update database set title =? where _id = ?";
  51. db.execSQL(sql, new String[]{String.valueOf(title), String.valueOf(id)});
  52. }

  53. //查询记录的总数
  54. public long getCount() {
  55. SQLiteDatabase db = dbHelper.getWritableDatabase();
  56. String sql = "select count(*) from database";
  57. Cursor c = db.rawQuery(sql, null);
  58. c.moveToFirst();
  59. long length = c.getLong(0);
  60. c.close();
  61. return length;
  62. }

  63. /**
  64. * 拿到所有的记录条数
  65. * @param firstResult 从第几条数据开始查询。
  66. * @param maxResult 每页显示多少条记录。
  67. * @return 当前页的记录
  68. */
  69. public Cursor getAllItems(int firstResult, int maxResult) {
  70. SQLiteDatabase db = dbHelper.getWritableDatabase();
  71. String sql = "select * from database limit ?,?";
  72. Cursor mCursor = db.rawQuery(sql, new String[]{String.valueOf(firstResult), String.valueOf(maxResult)});
  73. return mCursor;
  74. }
  75. }
复制代码
写一个布局。里面有一个ListView和2个Button:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. >
  7. <ListView
  8. android:id="@+id/testList"
  9. android:layout_width="match_parent"
  10. android:layout_height="0dip"
  11. android:layout_weight="3"/>
  12. <LinearLayout
  13. android:orientation="horizontal"
  14. android:layout_width="match_parent"
  15. android:layout_height="0dip"
  16. android:layout_weight="1">
  17. <Button
  18. android:id="@+id/leftButton"
  19. android:layout_width="wrap_content"
  20. android:layout_height="wrap_content"
  21. android:text="@string/previous"/>
  22. <Button
  23. android:id="@+id/rightButton"
  24. android:layout_width="wrap_content"
  25. android:layout_height="wrap_content"
  26. android:text="@string/next"/>
  27. </LinearLayout>
  28. </LinearLayout>
复制代码
我们需要对这个ListView设置一个Adapter,如下:
  1. package com.android.sqlite;

  2. import android.content.Context;
  3. import android.database.Cursor;
  4. import android.view.LayoutInflater;
  5. import android.view.View;
  6. import android.view.ViewGroup;
  7. import android.widget.CursorAdapter;
  8. import android.widget.TextView;

  9. import com.android.domain.Model;
  10. /**
  11. *
  12. * @author shangzhenxiang
  13. *
  14. */
  15. public class TestListAdapter extends CursorAdapter {

  16. private Context mContext;
  17. private Cursor mCursor;
  18. private Model mModel;
  19. private LayoutInflater mInflater;

  20. public TestListAdapter(Context context, Cursor c, Model model) {
  21. super(context, c);
  22. System.out.println("c = " + c);
  23. this.mContext = context;
  24. this.mCursor = c;
  25. this.mModel = model;
  26. mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  27. }

  28. @Override
  29. public View newView(Context context, Cursor cursor, ViewGroup parent) {
  30. return mInflater.inflate(R.layout.listitem, parent, false);
  31. }

  32. @Override
  33. public void bindView(View view, Context context, Cursor cursor) {
  34. ViewHolder holder = null;

  35. Object tag = view.getTag();
  36. if(tag instanceof ViewHolder) {
  37. holder = (ViewHolder) view.getTag();
  38. }
  39. if(holder == null) {
  40. holder = new ViewHolder();
  41. view.setTag(holder);
  42. holder.title = (TextView) view.findViewById(R.id.listitemtitle);
  43. }
  44. //将从数据库中查询到的title设为ListView的Item项。
  45. holder.title.setText(cursor.getString(cursor.getColumnIndexOrThrow("title")));
  46. }

  47. static class ViewHolder {
  48. TextView title;
  49. }
  50. }
复制代码
传进去一个Model的参数和一个Cursor。Model用于显示每页的个数和第几页,Cursor用于传递数据:  在Activity中我们对Button做监听:
  向左移的时候就将Model中的index减一,向右就加一,同时改变cursor中传进去的Model的值,刷新Adapter,刷新界面,
  同时检查Button的可用性:
  1. package com.android.sqlite;

  2. import android.app.Activity;
  3. import android.database.Cursor;
  4. import android.os.Bundle;
  5. import android.view.View;
  6. import android.view.View.OnClickListener;
  7. import android.widget.Button;
  8. import android.widget.ListView;

  9. import com.android.domain.Model;
  10. import com.android.service.DatabaseService;
  11. /**
  12. *
  13. * @author shangzhenxiang
  14. *
  15. */
  16. public class TestSqlite extends Activity implements OnClickListener {

  17. private ListView mListView;
  18. private TestListAdapter mTestListAdapter;
  19. private DatabaseService mDatabaseService;
  20. private Cursor mCursor;
  21. private Model mModel;
  22. private Button mLeftButton;
  23. private Button mRightButton;

  24. @Override
  25. public void onCreate(Bundle savedInstanceState) {
  26. super.onCreate(savedInstanceState);
  27. setContentView(R.layout.main);
  28. mListView = (ListView) findViewById(R.id.testList);
  29. //创建一个DatabaseService的对象。
  30. mDatabaseService = new DatabaseService(this);
  31. //创建一个Model的对象,表面这是首页,并且每页显示5个Item项
  32. mModel = new Model(0, 5);
  33. //mCursor查询到的是第0页的5个数据。
  34. mCursor = mDatabaseService.getAllItems(mModel.getIndex()*mModel.getView_Count(), mModel.getView_Count());
  35. System.out.println("mCursor = " + mCursor);
  36. //根据参数创建一个TestListAdapter对象,并设给ListView。
  37. mTestListAdapter = new TestListAdapter(this, mCursor, mModel);
  38. mListView.setAdapter(mTestListAdapter);
  39. mLeftButton = (Button) findViewById(R.id.leftButton);
  40. mRightButton = (Button) findViewById(R.id.rightButton);
  41. //设置Button的监听
  42. mLeftButton.setOnClickListener(this);
  43. mRightButton.setOnClickListener(this);
  44. checkButton();
  45. }

  46. //在Activity 销毁的时候记得将Cursor关掉。
  47. @Override
  48. protected void onDestroy() {
  49. // TODO Auto-generated method stub
  50. super.onDestroy();
  51. mCursor.close();
  52. }

  53. @Override
  54. public void onClick(View v) {
  55. // TODO Auto-generated method stub
  56. int id = v.getId();
  57. switch (id) {
  58. case R.id.leftButton:
  59. //页数向前翻一页,同时将Cursor重新查一遍,然后changeCursor,notifyDataSetChanged。
  60. //检查Button的可用性。
  61. mModel.setIndex(mModel.getIndex() - 1);
  62. mCursor = mDatabaseService.getAllItems(mModel.getIndex()*mModel.getView_Count(), mModel.getView_Count());
  63. mTestListAdapter.changeCursor(mCursor);
  64. mTestListAdapter.notifyDataSetChanged();
  65. checkButton();
  66. break;

  67. //页数向后翻一页,同时将Cursor重新查一遍,然后changeCursor,notifyDataSetChanged。
  68. //检查Button的可用性。
  69. case R.id.rightButton:
  70. mModel.setIndex(mModel.getIndex() + 1);
  71. mCursor = mDatabaseService.getAllItems(mModel.getIndex()*mModel.getView_Count(), mModel.getView_Count());
  72. mTestListAdapter.changeCursor(mCursor);
  73. mTestListAdapter.notifyDataSetChanged();
  74. checkButton();
  75. break;

  76. default:
  77. break;
  78. }
  79. }
  80. /**
  81. * 如果页数小于或等于0,表示在第一页,向左的按钮设为不可用,向右的按钮设为可用。
  82. * 如果总数目减前几页的数目,得到的是当前页的数目,如果比这一页要显示的少,则说明这是最后一页,向右的按钮不可用,向左的按钮可用。
  83. * 如果不是以上两种情况,则说明页数在中间,两个按钮都设为可用。
  84. */
  85. private void checkButton() {
  86. if(mModel.getIndex() <= 0) {
  87. mLeftButton.setEnabled(false);
  88. mRightButton.setEnabled(true);
  89. } else if(mDatabaseService.getCount() - mModel.getIndex()*mModel.getView_Count() <= mModel.getView_Count()) {
  90. mRightButton.setEnabled(false);
  91. mLeftButton.setEnabled(true);
  92. } else {
  93. mLeftButton.setEnabled(true);
  94. mRightButton.setEnabled(true);
  95. }
  96. }
  97. }
复制代码
代码中的注释写的比较清楚,记性不太好,留作以后复习用。代码:
TestSqlite
源文摘自:http://www.cnblogs.com/shang53880/archive/2011/03/11/1981749.html

该会员没有填写今日想说内容.
 楼主| 发表于 2012-12-19 13:18:03 | 显示全部楼层
该会员没有填写今日想说内容.
回复

使用道具 举报

升级  26%

0

主题

0

主题

0

主题

秀才

Rank: 2

积分
89
发表于 2013-2-5 03:51:52 | 显示全部楼层
提示: 该帖被管理员或版主屏蔽
回复

使用道具 举报

升级  26%

0

主题

0

主题

0

主题

秀才

Rank: 2

积分
89
发表于 2013-2-7 21:51:28 | 显示全部楼层
提示: 该帖被管理员或版主屏蔽
回复

使用道具 举报

升级  23.33%

0

主题

0

主题

0

主题

秀才

Rank: 2

积分
85
发表于 2013-2-24 16:03:40 | 显示全部楼层
今天没事来逛逛
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表