ListView上下翻页效果
2011-01-03 17:04 雪夜&流星 阅读(843) 评论(0) 编辑 收藏 举报先贴上效果图和代码,现在没有时间来解释,等明天有时间再把注释贴上来。
参考我在eoeAndroid中的文章:http://www.eoeandroid.com/thread-53980-1-1.html,那里面比较详细!
代码 Main:
代码
publicclass Main extends Activity {
private ListView listView;
private TextView preTextView, nextTextView, total, current;
//定义点击事件
private OnClickListener cl;
//定义适配器
private ListAdapter listadpter;
//定义每一页显示行数
privateint VIEW_COUNT =5;
//定义的页数
privateint index =0;
//泛型集合ArrayList
private ArrayList<Students> arrayList =new ArrayList<Students>();
//数据操作的dao类
StudentsDAO dao =new StudentsDAO(Main.this);
//实体bean
Students students =new Students();
// 标记:上次的ID
int last =0;
/** Called when the activity is first created. */
@Override
publicvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//初始化界面
initView();
//调用dao里面的insert()方法
dao.insert();
//调用dao里面的selectAll()方法
arrayList = dao.selectAll();
//实例化适配器
listadpter =new ListAdapter(Main.this);
//填充适配器
listView.setAdapter(listadpter);
//监听机制
cl =new TextView.OnClickListener() {
publicvoid onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
//如果是上一页textview的时候,调用上一页的方法
case R.id.txPreview:
preView();
break;
case R.id.txNext:
nextView();
break;
default:
break;
}
}
};
//Item点击事件
listView.setOnItemClickListener(new OnItemClickListener() {
publicvoid onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// TODO Auto-generated method stub
// 重置上次颜色为Color.WHITE
setLastColorBlack();
LinearLayout lLayout = (LinearLayout) view;
TextView lText = (TextView) lLayout.getChildAt(1);
lText.setTextColor(Color.RED);
// 保存最新的上次ID
last = position;
finalint pos = position;
Toast.makeText(
Main.this,
"This is "+ index +" page,is the "
+ String.valueOf(pos +1)
+" row,current date is "
+ arrayList.get(pos + index * VIEW_COUNT).getName(), Toast.LENGTH_SHORT)
.show();
}
});
//Item长按事件
listView.setOnItemLongClickListener(new OnItemLongClickListener() {
publicboolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id) {
// TODO Auto-generated method stub
// 重置上次颜色为Color.WHITE
setLastColorBlack();
LinearLayout lLayout = (LinearLayout) view;
TextView lText = (TextView) lLayout.getChildAt(1);
lText.setTextColor(Color.GREEN);
// 保存最新的上次ID
last = position;
finalint pos = position;
Toast.makeText(
Main.this,
"This is "+ index +" page,is the "
+ String.valueOf(pos +1)
+" row,current date is "
+ arrayList.get(pos + index * VIEW_COUNT).getName(), Toast.LENGTH_SHORT)
.show();
returnfalse;
}
});
preTextView.setOnClickListener(cl);
nextTextView.setOnClickListener(cl);
//总页数
total.setText("total:"+ String.valueOf(arrayList.size()));
//当前页数
current.setText("current:"+ String.valueOf(index));
checkView();
}
//初始化界面方法
privatevoid initView() {
// TODO Auto-generated method stub
listView = (ListView) findViewById(R.id.list);
preTextView = (TextView) findViewById(R.id.txPreview);
nextTextView = (TextView) findViewById(R.id.txNext);
total = (TextView) findViewById(R.id.total);
current = (TextView) findViewById(R.id.current);
}
publicvoid setLastColorBlack() {
//选中之后的颜色变成白色
LinearLayout lastLayout = (LinearLayout) listView.getChildAt(last);
TextView lastText = (TextView) lastLayout.getChildAt(1);
lastText.setTextColor(Color.WHITE);
}
//上一页的方法
privatevoid preView() {
// TODO Auto-generated method stub
index--;
current.setText("current:"+ String.valueOf(index));
//重新更新数据
listadpter.notifyDataSetChanged();
checkView();
}
//下一页的方法
privatevoid nextView() {
// TODO Auto-generated method stub
index++;
current.setText("current:"+ String.valueOf(index));
//重新更新数据
listadpter.notifyDataSetChanged();
checkView();
}
//检测是否到了第一页和最后一页
publicvoid checkView() {
if (index <=0) {
//如果页数小于0就让preTextView不可见
preTextView.setEnabled(false);
if (arrayList.size() <= VIEW_COUNT) {
//如果总长度小于VIEW_COUNT就让nextTextView不可见
nextTextView.setEnabled(false);
}
} elseif (arrayList.size() - index * VIEW_COUNT <= VIEW_COUNT) {
//当当前数据前进到最后一页的时候就让nextTextView不可见
nextTextView.setEnabled(false);
} else {
preTextView.setEnabled(true);
nextTextView.setEnabled(true);
}
}
//自定义适配器
class ListAdapter extends BaseAdapter {
Activity activity;
public ListAdapter(Activity activity) {
this.activity = activity;
}
publicvoid notifyDataSetChanged() {
// TODO Auto-generated method stub
//每次清空数据,重新填充
arrayList.clear();
arrayList = dao.selectAll();
super.notifyDataSetChanged();
}
publicint getCount() {
// TODO Auto-generated method stub
if (arrayList.size() - VIEW_COUNT * index < VIEW_COUNT) {
return arrayList.size() - VIEW_COUNT * index;
} else {
return VIEW_COUNT;
}
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
publiclong getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder holder;
if (arrayList !=null) {
//根据位置来获取数据
students = arrayList.get(position + index * VIEW_COUNT);
}
if (convertView ==null) {
convertView = getLayoutInflater().inflate(R.layout.list_item,
null);
holder =new ViewHolder();
holder.img=(TextView) convertView.findViewById(R.id.img);
holder.text = (TextView) convertView.findViewById(R.id.tv);
holder.ck = (CheckBox) convertView.findViewById(R.id.ck);
//设置标志符
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.img.setText("ID: "+students.getId());
holder.text.setText("Name: "+students.getName()+"——"+"Age:"+students.getAge());
finalint pos = position;
//设置TextView点击事件
holder.text.setOnClickListener(new OnClickListener() {
publicvoid onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(
Main.this,
"This is "+ index +" page,is the "
+ String.valueOf(pos +1)
+" row,current date is "
+ arrayList.get(pos + index * VIEW_COUNT).getName(), Toast.LENGTH_SHORT)
.show();
}
});
//设置CheckBox点击事件
holder.ck.setOnCheckedChangeListener(new OnCheckedChangeListener() {
publicvoid onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
// TODO Auto-generated method stub
if (isChecked) {
Toast.makeText(
Main.this,
"This is "+ index +" page,is the "
+ String.valueOf(pos +1)
+" row,current date is "
+ arrayList.get(pos + index * VIEW_COUNT).getName(),
Toast.LENGTH_SHORT).show();
}
}
});
return convertView;
}
}
finalclass ViewHolder {
TextView text;
TextView img;
CheckBox ck;
}
}
private ListView listView;
private TextView preTextView, nextTextView, total, current;
//定义点击事件
private OnClickListener cl;
//定义适配器
private ListAdapter listadpter;
//定义每一页显示行数
privateint VIEW_COUNT =5;
//定义的页数
privateint index =0;
//泛型集合ArrayList
private ArrayList<Students> arrayList =new ArrayList<Students>();
//数据操作的dao类
StudentsDAO dao =new StudentsDAO(Main.this);
//实体bean
Students students =new Students();
// 标记:上次的ID
int last =0;
/** Called when the activity is first created. */
@Override
publicvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//初始化界面
initView();
//调用dao里面的insert()方法
dao.insert();
//调用dao里面的selectAll()方法
arrayList = dao.selectAll();
//实例化适配器
listadpter =new ListAdapter(Main.this);
//填充适配器
listView.setAdapter(listadpter);
//监听机制
cl =new TextView.OnClickListener() {
publicvoid onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
//如果是上一页textview的时候,调用上一页的方法
case R.id.txPreview:
preView();
break;
case R.id.txNext:
nextView();
break;
default:
break;
}
}
};
//Item点击事件
listView.setOnItemClickListener(new OnItemClickListener() {
publicvoid onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// TODO Auto-generated method stub
// 重置上次颜色为Color.WHITE
setLastColorBlack();
LinearLayout lLayout = (LinearLayout) view;
TextView lText = (TextView) lLayout.getChildAt(1);
lText.setTextColor(Color.RED);
// 保存最新的上次ID
last = position;
finalint pos = position;
Toast.makeText(
Main.this,
"This is "+ index +" page,is the "
+ String.valueOf(pos +1)
+" row,current date is "
+ arrayList.get(pos + index * VIEW_COUNT).getName(), Toast.LENGTH_SHORT)
.show();
}
});
//Item长按事件
listView.setOnItemLongClickListener(new OnItemLongClickListener() {
publicboolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id) {
// TODO Auto-generated method stub
// 重置上次颜色为Color.WHITE
setLastColorBlack();
LinearLayout lLayout = (LinearLayout) view;
TextView lText = (TextView) lLayout.getChildAt(1);
lText.setTextColor(Color.GREEN);
// 保存最新的上次ID
last = position;
finalint pos = position;
Toast.makeText(
Main.this,
"This is "+ index +" page,is the "
+ String.valueOf(pos +1)
+" row,current date is "
+ arrayList.get(pos + index * VIEW_COUNT).getName(), Toast.LENGTH_SHORT)
.show();
returnfalse;
}
});
preTextView.setOnClickListener(cl);
nextTextView.setOnClickListener(cl);
//总页数
total.setText("total:"+ String.valueOf(arrayList.size()));
//当前页数
current.setText("current:"+ String.valueOf(index));
checkView();
}
//初始化界面方法
privatevoid initView() {
// TODO Auto-generated method stub
listView = (ListView) findViewById(R.id.list);
preTextView = (TextView) findViewById(R.id.txPreview);
nextTextView = (TextView) findViewById(R.id.txNext);
total = (TextView) findViewById(R.id.total);
current = (TextView) findViewById(R.id.current);
}
publicvoid setLastColorBlack() {
//选中之后的颜色变成白色
LinearLayout lastLayout = (LinearLayout) listView.getChildAt(last);
TextView lastText = (TextView) lastLayout.getChildAt(1);
lastText.setTextColor(Color.WHITE);
}
//上一页的方法
privatevoid preView() {
// TODO Auto-generated method stub
index--;
current.setText("current:"+ String.valueOf(index));
//重新更新数据
listadpter.notifyDataSetChanged();
checkView();
}
//下一页的方法
privatevoid nextView() {
// TODO Auto-generated method stub
index++;
current.setText("current:"+ String.valueOf(index));
//重新更新数据
listadpter.notifyDataSetChanged();
checkView();
}
//检测是否到了第一页和最后一页
publicvoid checkView() {
if (index <=0) {
//如果页数小于0就让preTextView不可见
preTextView.setEnabled(false);
if (arrayList.size() <= VIEW_COUNT) {
//如果总长度小于VIEW_COUNT就让nextTextView不可见
nextTextView.setEnabled(false);
}
} elseif (arrayList.size() - index * VIEW_COUNT <= VIEW_COUNT) {
//当当前数据前进到最后一页的时候就让nextTextView不可见
nextTextView.setEnabled(false);
} else {
preTextView.setEnabled(true);
nextTextView.setEnabled(true);
}
}
//自定义适配器
class ListAdapter extends BaseAdapter {
Activity activity;
public ListAdapter(Activity activity) {
this.activity = activity;
}
publicvoid notifyDataSetChanged() {
// TODO Auto-generated method stub
//每次清空数据,重新填充
arrayList.clear();
arrayList = dao.selectAll();
super.notifyDataSetChanged();
}
publicint getCount() {
// TODO Auto-generated method stub
if (arrayList.size() - VIEW_COUNT * index < VIEW_COUNT) {
return arrayList.size() - VIEW_COUNT * index;
} else {
return VIEW_COUNT;
}
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
publiclong getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder holder;
if (arrayList !=null) {
//根据位置来获取数据
students = arrayList.get(position + index * VIEW_COUNT);
}
if (convertView ==null) {
convertView = getLayoutInflater().inflate(R.layout.list_item,
null);
holder =new ViewHolder();
holder.img=(TextView) convertView.findViewById(R.id.img);
holder.text = (TextView) convertView.findViewById(R.id.tv);
holder.ck = (CheckBox) convertView.findViewById(R.id.ck);
//设置标志符
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.img.setText("ID: "+students.getId());
holder.text.setText("Name: "+students.getName()+"——"+"Age:"+students.getAge());
finalint pos = position;
//设置TextView点击事件
holder.text.setOnClickListener(new OnClickListener() {
publicvoid onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(
Main.this,
"This is "+ index +" page,is the "
+ String.valueOf(pos +1)
+" row,current date is "
+ arrayList.get(pos + index * VIEW_COUNT).getName(), Toast.LENGTH_SHORT)
.show();
}
});
//设置CheckBox点击事件
holder.ck.setOnCheckedChangeListener(new OnCheckedChangeListener() {
publicvoid onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
// TODO Auto-generated method stub
if (isChecked) {
Toast.makeText(
Main.this,
"This is "+ index +" page,is the "
+ String.valueOf(pos +1)
+" row,current date is "
+ arrayList.get(pos + index * VIEW_COUNT).getName(),
Toast.LENGTH_SHORT).show();
}
}
});
return convertView;
}
}
finalclass ViewHolder {
TextView text;
TextView img;
CheckBox ck;
}
}
实体Bean Students:
代码
publicclass Students {
publicint id;
public String name;
publicint age;
public Students() {
super();
// TODO Auto-generated constructor stub
}
public Students(int id, String name, int age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
publicint getId() {
return id;
}
publicvoid setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
publicvoid setName(String name) {
this.name = name;
}
publicint getAge() {
return age;
}
publicvoid setAge(int age) {
this.age = age;
}
}
publicint id;
public String name;
publicint age;
public Students() {
super();
// TODO Auto-generated constructor stub
}
public Students(int id, String name, int age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
publicint getId() {
return id;
}
publicvoid setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
publicvoid setName(String name) {
this.name = name;
}
publicint getAge() {
return age;
}
publicvoid setAge(int age) {
this.age = age;
}
}
数据库操作 StudentsDAO:
代码
publicclass StudentsDAO extends SDSQLiteOpenHelper {
privatefinalstatic String AUDIODATABASE_NAME ="student.db";
privatefinalstatic String TABLE ="student";
privatefinalstatic String COLUM_ID ="id";
privatefinalstatic String COLUM_NAME ="name";
privatefinalstatic String COLUM_AGE ="age";
privatefinalstaticint DATABASE_VERSION =1;
privatelong row;
private ArrayList<Students> arrayList;
public StudentsDAO(Context context) {
super(context, AUDIODATABASE_NAME, null, DATABASE_VERSION);
// TODO Auto-generated constructor stub
}
@Override
publicvoid onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
String sql ="CREATE TABLE "+ TABLE +" ("+ COLUM_ID
+" INTEGER primary key autoincrement, "+""+ COLUM_NAME
+" text, "+""+ COLUM_AGE +" int)";
db.execSQL(sql);
}
@Override
publicvoid onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
String sql ="DROP TABLE IF EXISTS "+ TABLE;
db.execSQL(sql);
}
publiclong insert() {
SQLiteDatabase db = getWritableDatabase();
ContentValues cv =new ContentValues();
Random random =new Random();
for(int i=1;i<=100;i++)
{
cv.put(COLUM_ID, i);
cv.put(COLUM_NAME, "name"+String.valueOf(i));
cv.put(COLUM_AGE, random.nextInt(100));
row = db.insert(TABLE, null, cv);
}
db.close();
return row;
}
public ArrayList<Students> selectAll() {
arrayList=new ArrayList<Students>();
SQLiteDatabase db =this.getWritableDatabase();
Cursor cursor = db.query(TABLE, null, null, null, null, null, null);
if (cursor !=null&& cursor.getCount() >0) {
cursor.moveToFirst();
}
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
Students students=new Students();
students.setId(cursor.getInt(0));
students.setName(cursor.getString(1));
students.setAge(cursor.getInt(2));
arrayList.add(students);
}
cursor.close();
db.close();
return arrayList;
}
}
privatefinalstatic String AUDIODATABASE_NAME ="student.db";
privatefinalstatic String TABLE ="student";
privatefinalstatic String COLUM_ID ="id";
privatefinalstatic String COLUM_NAME ="name";
privatefinalstatic String COLUM_AGE ="age";
privatefinalstaticint DATABASE_VERSION =1;
privatelong row;
private ArrayList<Students> arrayList;
public StudentsDAO(Context context) {
super(context, AUDIODATABASE_NAME, null, DATABASE_VERSION);
// TODO Auto-generated constructor stub
}
@Override
publicvoid onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
String sql ="CREATE TABLE "+ TABLE +" ("+ COLUM_ID
+" INTEGER primary key autoincrement, "+""+ COLUM_NAME
+" text, "+""+ COLUM_AGE +" int)";
db.execSQL(sql);
}
@Override
publicvoid onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
String sql ="DROP TABLE IF EXISTS "+ TABLE;
db.execSQL(sql);
}
publiclong insert() {
SQLiteDatabase db = getWritableDatabase();
ContentValues cv =new ContentValues();
Random random =new Random();
for(int i=1;i<=100;i++)
{
cv.put(COLUM_ID, i);
cv.put(COLUM_NAME, "name"+String.valueOf(i));
cv.put(COLUM_AGE, random.nextInt(100));
row = db.insert(TABLE, null, cv);
}
db.close();
return row;
}
public ArrayList<Students> selectAll() {
arrayList=new ArrayList<Students>();
SQLiteDatabase db =this.getWritableDatabase();
Cursor cursor = db.query(TABLE, null, null, null, null, null, null);
if (cursor !=null&& cursor.getCount() >0) {
cursor.moveToFirst();
}
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
Students students=new Students();
students.setId(cursor.getInt(0));
students.setName(cursor.getString(1));
students.setAge(cursor.getInt(2));
arrayList.add(students);
}
cursor.close();
db.close();
return arrayList;
}
}
SDSQLiteOpenHelper:
代码
publicabstractclass SDSQLiteOpenHelper {
privatestaticfinal String TAG = SDSQLiteOpenHelper.class.getSimpleName();
@SuppressWarnings("unused")
privatefinal Context mContext;
privatefinal String mName;
privatefinal CursorFactory mFactory;
privatefinalint mNewVersion;
private SQLiteDatabase mDatabase =null;
privateboolean mIsInitializing =false;
/**
* Create a helper object to create, open, and/or manage a database. The
* database is not actually created or opened until one of
* {@link #getWritableDatabase} or {@link #getReadableDatabase} is called.
*
* @param context
* to use to open or create the database
* @param name
* of the database file, or null for an in-memory database
* @param factory
* to use for creating cursor objects, or null for the default
* @param version
* number of the database (starting at 1); if the database is
* older, {@link #onUpgrade} will be used to upgrade the database
*/
public SDSQLiteOpenHelper(Context context, String name,
CursorFactory factory, int version) {
if (version <1)
thrownew IllegalArgumentException("Version must be >= 1, was "
+ version);
mContext = context;
mName = name;
mFactory = factory;
mNewVersion = version;
}
/**
* Create and/or open a database that will be used for reading and writing.
* Once opened successfully, the database is cached, so you can call this
* method every time you need to write to the database. Make sure to call
* {@link #close} when you no longer need it.
*
* <p>
* Errors such as bad permissions or a full disk may cause this operation to
* fail, but future attempts may succeed if the problem is fixed.
* </p>
*
* @throws SQLiteException
* if the database cannot be opened for writing
* @return a read/write database object valid until {@link #close} is called
*/
publicsynchronized SQLiteDatabase getWritableDatabase() {
if (mDatabase !=null&& mDatabase.isOpen() &&!mDatabase.isReadOnly()) {
return mDatabase; // The database is already open for business
}
if (mIsInitializing) {
thrownew IllegalStateException(
"getWritableDatabase called recursively");
}
// If we have a read-only database open, someone could be using it
// (though they shouldn't), which would cause a lock to be held on
// the file, and our attempts to open the database read-write would
// fail waiting for the file lock. To prevent that, we acquire the
// lock on the read-only database, which shuts out other users.
boolean success =false;
SQLiteDatabase db =null;
try {
mIsInitializing =true;
if (mName ==null) {
db = SQLiteDatabase.create(null);
} else {
String path = getDatabasePath(mName).getPath();
db = SQLiteDatabase.openOrCreateDatabase(path, mFactory);
}
int version = db.getVersion();
if (version != mNewVersion) {
db.beginTransaction();
try {
if (version ==0) {
onCreate(db);
} else {
onUpgrade(db, version, mNewVersion);
}
db.setVersion(mNewVersion);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
onOpen(db);
success =true;
return db;
} finally {
mIsInitializing =false;
if (success) {
if (mDatabase !=null) {
try {
mDatabase.close();
} catch (Exception e) {
}
}
mDatabase = db;
} else {
if (db !=null)
db.close();
}
}
}
/**
* Create and/or open a database. This will be the same object returned by
* {@link #getWritableDatabase} unless some problem, such as a full disk,
* requires the database to be opened read-only. In that case, a read-only
* database object will be returned. If the problem is fixed, a future call
* to {@link #getWritableDatabase} may succeed, in which case the read-only
* database object will be closed and the read/write object will be returned
* in the future.
*
* @throws SQLiteException
* if the database cannot be opened
* @return a database object valid until {@link #getWritableDatabase} or
* {@link #close} is called.
*/
publicsynchronized SQLiteDatabase getReadableDatabase() {
if (mDatabase !=null&& mDatabase.isOpen()) {
return mDatabase; // The database is already open for business
}
if (mIsInitializing) {
thrownew IllegalStateException(
"getReadableDatabase called recursively");
}
try {
return getWritableDatabase();
} catch (SQLiteException e) {
if (mName ==null)
throw e; // Can't open a temp database read-only!
Log.e(TAG, "Couldn't open "+ mName
+" for writing (will try read-only):", e);
}
SQLiteDatabase db =null;
try {
mIsInitializing =true;
String path = getDatabasePath(mName).getPath();
db = SQLiteDatabase.openDatabase(path, mFactory,
SQLiteDatabase.OPEN_READWRITE);
if (db.getVersion() != mNewVersion) {
thrownew SQLiteException(
"Can't upgrade read-only database from version "
+ db.getVersion() +" to "+ mNewVersion +": "
+ path);
}
onOpen(db);
Log.w(TAG, "Opened "+ mName +" in read-only mode");
mDatabase = db;
return mDatabase;
} finally {
mIsInitializing =false;
if (db !=null&& db != mDatabase)
db.close();
}
}
/**
* Close any open database object.
*/
publicsynchronizedvoid close() {
if (mIsInitializing)
thrownew IllegalStateException("Closed during initialization");
if (mDatabase !=null&& mDatabase.isOpen()) {
mDatabase.close();
mDatabase =null;
}
}
public File getDatabasePath(String name) {
String EXTERN_PATH =null;
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)==true)
{
EXTERN_PATH = android.os.Environment.getExternalStorageDirectory().getAbsolutePath()
+"/db/";
File f=new File(EXTERN_PATH);
if(!f.exists())
{
f.mkdirs();
}
}
returnnew File(EXTERN_PATH+ name);
}
/**
* Called when the database is created for the first time. This is where the
* creation of tables and the initial population of the tables should
* happen.
*
* @param db
* The database.
*/
publicabstractvoid onCreate(SQLiteDatabase db);
/**
* Called when the database needs to be upgraded. The implementation should
* use this method to drop tables, add tables, or do anything else it needs
* to upgrade to the new schema version.
*
* <p>
* The SQLite ALTER TABLE documentation can be found <a
* href="http://sqlite.org/lang_altertable.html">here</a>. If you add new
* columns you can use ALTER TABLE to insert them into a live table. If you
* rename or remove columns you can use ALTER TABLE to rename the old table,
* then create the new table and then populate the new table with the
* contents of the old table.
*
* @param db
* The database.
* @param oldVersion
* The old database version.
* @param newVersion
* The new database version.
*/
publicabstractvoid onUpgrade(SQLiteDatabase db, int oldVersion,
int newVersion);
/**
* Called when the database has been opened. Override method should check
* {@link SQLiteDatabase#isReadOnly} before updating the database.
*
* @param db
* The database.
*/
publicvoid onOpen(SQLiteDatabase db) {
}
}
privatestaticfinal String TAG = SDSQLiteOpenHelper.class.getSimpleName();
@SuppressWarnings("unused")
privatefinal Context mContext;
privatefinal String mName;
privatefinal CursorFactory mFactory;
privatefinalint mNewVersion;
private SQLiteDatabase mDatabase =null;
privateboolean mIsInitializing =false;
/**
* Create a helper object to create, open, and/or manage a database. The
* database is not actually created or opened until one of
* {@link #getWritableDatabase} or {@link #getReadableDatabase} is called.
*
* @param context
* to use to open or create the database
* @param name
* of the database file, or null for an in-memory database
* @param factory
* to use for creating cursor objects, or null for the default
* @param version
* number of the database (starting at 1); if the database is
* older, {@link #onUpgrade} will be used to upgrade the database
*/
public SDSQLiteOpenHelper(Context context, String name,
CursorFactory factory, int version) {
if (version <1)
thrownew IllegalArgumentException("Version must be >= 1, was "
+ version);
mContext = context;
mName = name;
mFactory = factory;
mNewVersion = version;
}
/**
* Create and/or open a database that will be used for reading and writing.
* Once opened successfully, the database is cached, so you can call this
* method every time you need to write to the database. Make sure to call
* {@link #close} when you no longer need it.
*
* <p>
* Errors such as bad permissions or a full disk may cause this operation to
* fail, but future attempts may succeed if the problem is fixed.
* </p>
*
* @throws SQLiteException
* if the database cannot be opened for writing
* @return a read/write database object valid until {@link #close} is called
*/
publicsynchronized SQLiteDatabase getWritableDatabase() {
if (mDatabase !=null&& mDatabase.isOpen() &&!mDatabase.isReadOnly()) {
return mDatabase; // The database is already open for business
}
if (mIsInitializing) {
thrownew IllegalStateException(
"getWritableDatabase called recursively");
}
// If we have a read-only database open, someone could be using it
// (though they shouldn't), which would cause a lock to be held on
// the file, and our attempts to open the database read-write would
// fail waiting for the file lock. To prevent that, we acquire the
// lock on the read-only database, which shuts out other users.
boolean success =false;
SQLiteDatabase db =null;
try {
mIsInitializing =true;
if (mName ==null) {
db = SQLiteDatabase.create(null);
} else {
String path = getDatabasePath(mName).getPath();
db = SQLiteDatabase.openOrCreateDatabase(path, mFactory);
}
int version = db.getVersion();
if (version != mNewVersion) {
db.beginTransaction();
try {
if (version ==0) {
onCreate(db);
} else {
onUpgrade(db, version, mNewVersion);
}
db.setVersion(mNewVersion);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
onOpen(db);
success =true;
return db;
} finally {
mIsInitializing =false;
if (success) {
if (mDatabase !=null) {
try {
mDatabase.close();
} catch (Exception e) {
}
}
mDatabase = db;
} else {
if (db !=null)
db.close();
}
}
}
/**
* Create and/or open a database. This will be the same object returned by
* {@link #getWritableDatabase} unless some problem, such as a full disk,
* requires the database to be opened read-only. In that case, a read-only
* database object will be returned. If the problem is fixed, a future call
* to {@link #getWritableDatabase} may succeed, in which case the read-only
* database object will be closed and the read/write object will be returned
* in the future.
*
* @throws SQLiteException
* if the database cannot be opened
* @return a database object valid until {@link #getWritableDatabase} or
* {@link #close} is called.
*/
publicsynchronized SQLiteDatabase getReadableDatabase() {
if (mDatabase !=null&& mDatabase.isOpen()) {
return mDatabase; // The database is already open for business
}
if (mIsInitializing) {
thrownew IllegalStateException(
"getReadableDatabase called recursively");
}
try {
return getWritableDatabase();
} catch (SQLiteException e) {
if (mName ==null)
throw e; // Can't open a temp database read-only!
Log.e(TAG, "Couldn't open "+ mName
+" for writing (will try read-only):", e);
}
SQLiteDatabase db =null;
try {
mIsInitializing =true;
String path = getDatabasePath(mName).getPath();
db = SQLiteDatabase.openDatabase(path, mFactory,
SQLiteDatabase.OPEN_READWRITE);
if (db.getVersion() != mNewVersion) {
thrownew SQLiteException(
"Can't upgrade read-only database from version "
+ db.getVersion() +" to "+ mNewVersion +": "
+ path);
}
onOpen(db);
Log.w(TAG, "Opened "+ mName +" in read-only mode");
mDatabase = db;
return mDatabase;
} finally {
mIsInitializing =false;
if (db !=null&& db != mDatabase)
db.close();
}
}
/**
* Close any open database object.
*/
publicsynchronizedvoid close() {
if (mIsInitializing)
thrownew IllegalStateException("Closed during initialization");
if (mDatabase !=null&& mDatabase.isOpen()) {
mDatabase.close();
mDatabase =null;
}
}
public File getDatabasePath(String name) {
String EXTERN_PATH =null;
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)==true)
{
EXTERN_PATH = android.os.Environment.getExternalStorageDirectory().getAbsolutePath()
+"/db/";
File f=new File(EXTERN_PATH);
if(!f.exists())
{
f.mkdirs();
}
}
returnnew File(EXTERN_PATH+ name);
}
/**
* Called when the database is created for the first time. This is where the
* creation of tables and the initial population of the tables should
* happen.
*
* @param db
* The database.
*/
publicabstractvoid onCreate(SQLiteDatabase db);
/**
* Called when the database needs to be upgraded. The implementation should
* use this method to drop tables, add tables, or do anything else it needs
* to upgrade to the new schema version.
*
* <p>
* The SQLite ALTER TABLE documentation can be found <a
* href="http://sqlite.org/lang_altertable.html">here</a>. If you add new
* columns you can use ALTER TABLE to insert them into a live table. If you
* rename or remove columns you can use ALTER TABLE to rename the old table,
* then create the new table and then populate the new table with the
* contents of the old table.
*
* @param db
* The database.
* @param oldVersion
* The old database version.
* @param newVersion
* The new database version.
*/
publicabstractvoid onUpgrade(SQLiteDatabase db, int oldVersion,
int newVersion);
/**
* Called when the database has been opened. Override method should check
* {@link SQLiteDatabase#isReadOnly} before updating the database.
*
* @param db
* The database.
*/
publicvoid onOpen(SQLiteDatabase db) {
}
}