您的位置:首页 > 电脑网络 > 笔记本 > ListView实现Gallery自定义列表 - Android开发专区【初|中|高】级 - CMD100 中国手机开发

ListView实现Gallery自定义列表 - Android开发专区【初|中|高】级 - CMD100 中国手机开发

luyued 发布于 2011-04-20 15:43   浏览 N 次  

三零梦 |设置 |管理菜单|提醒 |短消息 |好友 邀请 | 任务 |退出

积分: 2 , 威望: 0 , 铜币: 3 , 软件收益: 0 , 金盾: 0 , 用户组: 扫盲班

签到天数: 95 天

连续签到: 20 天

[LV.6]HTC6

本帖最后由 wanglin5659643 于 2011-4-14 21:51 编辑

从界面变化来看,主要是增加了自定义对话框,以及列表形式的切换。看附件一长按后还是显示checkbox。点击view按钮,将出现对话框:看附件二
如果touch对话框以外的区域,对话框将消失,这就比较类似ios里的popover了。

view mode下的radio按钮,可以切换列表形式,比如从缩略图(默认的模式)转换到列表模式下。

说一下如何实现自定义对话框。大致步骤有:

编写类,继承Dialog

覆盖超类的onTouchEvent方法。基本思路是在该方法中,判断一下touch的坐标是在对话框包含的视图坐标里还是外,如果是外,就hide(或者也可dismess)对话框对象。

Java代码:
package wanglin.android;

class MyDialog extends Dialog {

public MyDialog(Context context) {
super(context);
}

public MyDialog(Context context, boolean cancelable,
OnCancelListener cancelListener) {
super(context, cancelable, cancelListener);
}

public MyDialog(Context context, int theme) {
super(context, theme);
}

/**
* 处理触摸事件,如果触摸超出对话框范围,则对话框退出
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
Rect rect = new Rect();
View view = findViewById(R.id.dialogLayout);// 取对话框最外层视图
view.getWindowVisibleDisplayFrame(rect);// 得到window的矩形

// 因为对话框居中,因此对话框相对于window的坐标可通过对话框长和宽以及window矩形计算出来
Rect rect2 = new Rect((rect.right – view.getRight()) / 2,
(rect.bottom – view.getBottom()) / 2, view.getRight()
+ (rect.right – view.getRight()) / 2,
view.getBottom() + (rect.bottom – view.getBottom()));

if (!rect2.contains((int) event.getRawX(), (int) event.getRawY())) {
this.dismiss();
return true;
}
return super.onTouchEvent(event);
}
}复制代码切换表的表现形式,说起来很简单,其实就是为ListView设置不同的adapter即可。即:ListView.setAdapter()方法。每次设置不同的adapter实例,就会即可改变列表的表现形式。

在本例中,因为有数据的变化等因素,代码比ListView实现Gallery效果系列二要复杂很多。

另外,本例使用sqlite数据库替代了大部分原来用数组和列表模拟的数据集合。见com.easymorse.list.datasource包下的三个类,是一个标准的dao实现。dao的代码,主要实现了crud。代码:

Java代码:


package wanglin.android;

/**
* Record dao对象
*
* @author marshal
*
*/
public class RecordDao {

@SuppressWarnings("unused")
private static final String TAG = "listview";

// 由于模拟图片数据
private static final int[] drawables = { R.drawable.a1, R.drawable.a2,
R.drawable.a3, R.drawable.a4, R.drawable.a5, R.drawable.a6,
R.drawable.a7, R.drawable.a8, R.drawable.a9, R.drawable.a10,
R.drawable.a12, R.drawable.a13 };

// 图片的缓存,使用SoftReference是为了防止oom
private static Map> drawableCache = new HashMap>();

private Context context;

private SQLiteDatabase database;

public RecordDao(Context context) {
this.context = context;
init();
}

/**
* 通过缓存获取图片对象
*
* @param id
* 图片的id
* @return
*/
public Drawable getDrawable(Long id) {
// 如果缓存中有,使用缓存的
if (drawableCache.get(id) != null
&& drawableCache.get(id).get() != null) {
return drawableCache.get(id).get();
}

// 未在缓存中,可能是没加入缓存,也可能是垃圾回收,则重新获取,并加载缓存中
if (id >= 1 && id <= drawables.length) {
Drawable drawable = context.getResources().getDrawable(
drawables[id.intValue() - 1]);
drawableCache.put(id, new SoftReference(drawable));
return drawable;
}
return null;
}

private void init() {
this.database = context.openOrCreateDatabase("mydata",
Context.MODE_PRIVATE, null);

//TODO 正式使用时,取消下面初始化代码,改为使用SQLiteOpenHelper
dropTables();
createTables();

for (int i = 0; i < 12; i++) {
create(new Record(null, "柴可夫司机"));
}
}

public void create(Record record) {
SQLiteStatement statement = database
.compileStatement("insert into mydata (name) values(?)");
statement.bindString(1, record.getName());
statement.execute();
statement.close();

//需要设置record的id,否则没有唯一标识,无法和数据库交互
Cursor cursor = database.rawQuery(
"select last_insert_rowid() from mydata", new String[] {});
if (cursor.moveToFirst()) {
record.setId(cursor.getLong(0));
}
cursor.close();
}

public void browse(Page page) {
page.setResults(new ArrayList());
Cursor cursor = database.rawQuery("select count(*) from mydata ",
new String[] {});
if (cursor.moveToFirst()) {
page.setCount(cursor.getInt(0));
}
cursor.close();

if (page.getCount() > page.getSize() * (page.getNo() – 1)) {
cursor = database.rawQuery(
"select id,name from mydata limit " + page.getSize()
* (page.getNo() – 1) + " , " + page.getSize(),
new String[] {});//使用limit子句

while (cursor.moveToNext()) {
Record record = new Record(cursor.getLong(0),
cursor.getString(1));
page.getResults().add(record);
}
cursor.close();
}
}

public void delete(Long id) {
SQLiteStatement statement = database
.compileStatement("delete from mydata where );
statement.bindLong(1, id);
statement.execute();
statement.close();
}

public Record get(Long id) {
Record record = null;
Cursor cursor = database.rawQuery("select name from mydata where >+ id, new String[] {});
if (cursor.moveToFirst()) {
record = new Record();
record.setName(cursor.getString(0));
record.setId(id);
}
cursor.close();
return record;
}

private void dropTables() {
database.execSQL("drop table if exists mydata");
}

private void createTables() {
database.execSQL("create table if not exists mydata("
+ " id integer primary key autoincrement," + " name text" + ")");
}
}复制代码另外,这里做了个简单的缓存Drawable对象,使用SoftReference,软引用,这样当虚拟机内存够用的时候保持在内存中。当内存不足才清除。





GMT+8, 2011-4-14 22:30 , Processed in 0.190376 second(s), 32 queries .

(c) 2010-2011




引文来源 ListView实现Gallery自定义列表 - Android开发专区【初|中|高】级 - CMD100 中国手机开发者联盟
广告赞助商