android listview gallery,Android ListView专题之五 实现类似Gallery的功能

利用ListView,实现类似Android Gallery的功能。效果类似这样:

a4c26d1e5885305701be709a3d33442f.png

a4c26d1e5885305701be709a3d33442f.png

长按列表中元素:

a4c26d1e5885305701be709a3d33442f.png

勾选列表中元素,点击“选择”按钮:

a4c26d1e5885305701be709a3d33442f.png

a4c26d1e5885305701be709a3d33442f.png

点击删除按钮,则删掉所选元素:

a4c26d1e5885305701be709a3d33442f.png

a4c26d1e5885305701be709a3d33442f.png

再次长按屏幕中元素,按钮和多选框消失。另外,按系统回退按钮也可使按钮和多选框消失。如果没有多选框和按钮的时候,回退按钮将执行系统操作,退出应用。

实现这部分代码有几个难点:

长按界面中元素,所有元素都显示CheckBox,当然可以遍历所有元素(视图)并设置相应的CheckBox为visible,这样逻辑会比较乱,本例中使用了java提供的对观察者模式的支持类

删除其中某几个元素,应该保持在当前位置,其他相邻元素填补删除的空缺

下面说说难点的实现方法。先说观察者模式。实际上是引入了第三个对象,可观察对象,你可以把它看作中间人,所有元素都在这个中间人对象上注册了监听器,当其中一个被长按后,通知所有元素设置checkbox。

可以通过:

中的示例了解观察者模式以及java Observer的使用方法。

在本例中,通过内部类实现了Observable接口:

class MyObservable extends Observable {

public void

toobarStatusChanged(boolean visible) {

setChanged();

notifyObservers(visible);

}

}

这里实现了Observer的继承类,并为每个元素创建示例注册到Observable中:

// 创建观察者,用于监控是否有Checkbox可见性事件,然后加入到可观察对象中

Observer observer = new Observer() {

@Override

public void

update(Observable observable, Object data) {

checkBox.setVisibility((Boolean) data ? View.VISIBLE

: View.INVISIBLE);

checkBox.setChecked(checkedIds.contains(index));

}

};

observable.addObserver(observer);

另外,实现了一个Observer实例用于监控长按事件的变化,来生成或者取消工具条按钮。

这个实现目前可以工作,但是可能还有问题,造成大量的Observer对象的存在,因为每次创建ListView的Row都会重新创建,等有时间再解决。

如何做到删除其中几个元素,后面相邻元素自动补位,而且屏幕保持在当前位置。我的做法基本思路是,取到当前屏幕显示的各行,在Nexusone的分辨率下可取到3行,然后获取各行的ViewGroup对象,清空它的子视图,然后再根据数据源(本文是一个List)重新填充行的内容。

如何得到当前在屏幕的行的ViewGroup呢?其实并不复杂:

myListView.getChildCount()

可得到屏幕上能看到几行。

再通过遍历:

myListView.getChildAt(i)

就可以得到各行的ViewGroup。ListView的实现原理是,只保存当前可见的几行视图。并保存在ViewGroup的childView数组中,上述的两个方法getChildCount和getChildAt实际上是ViewGroup的,ListView并未覆盖。

完整的代码类似这样:

for (int i = 0; i < myListView.getChildCount(); i++)

{

ViewGroup

viewgroup = (ViewGroup) myListView.getChildAt(i);

viewgroup.removeAllViews();

generateRowElements(

myListView.getPositionForView(viewgroup), viewgroup);

}

完整源代码包含了详细的注释:

package com.easymorse.list;

import java.util.ArrayList;

import java.util.Collections;

import java.util.HashSet;

import java.util.List;

import java.util.Observable;

import java.util.Observer;

import java.util.Set;

import android.app.Activity;

import android.os.Bundle;

import android.view.KeyEvent;

import android.view.View;

import android.view.View.OnClickListener;

import android.view.View.OnKeyListener;

import android.view.View.OnLongClickListener;

import android.view.ViewGroup;

import android.widget.BaseAdapter;

import android.widget.Button;

import android.widget.CheckBox;

import android.widget.CompoundButton;

import android.widget.CompoundButton.OnCheckedChangeListener;

import android.widget.ImageView;

import android.widget.ListView;

import android.widget.TextView;

import android.widget.Toast;

public class ListViewDemoActivity extends Activity {

class

MyObservable extends Observable {

public void toobarStatusChanged(boolean visible) {

setChanged();

notifyObservers(visible);

}

}

//

每行显示几个图片

private

static final int ROW_ELEMENTS_SIZE = 5;

//

本例中的ListView

private

ListView myListView;

//

checkbox是否可见的标志位

private

boolean checkItemVisible;

private

ViewGroup toolbar;

//

存放选中的checkbox条目的图片列表下标

private

Set checkedIds = new

HashSet();

//

创建观察对象

private

MyObservable observable = new MyObservable();

//

演示用的图片数据集合

@SuppressWarnings("serial")

private

List drawables = new

ArrayList() {

{

add(R.drawable.defense_mechanism);

add(R.drawable.gzorah);

add(R.drawable.jay_z_linkin_park);

add(R.drawable.korn);

add(R.drawable.defense_mechanism);

add(R.drawable.gzorah);

add(R.drawable.jay_z_linkin_park);

add(R.drawable.korn);

add(R.drawable.defense_mechanism);

add(R.drawable.gzorah);

add(R.drawable.jay_z_linkin_park);

add(R.drawable.korn);

add(R.drawable.defense_mechanism);

add(R.drawable.gzorah);

add(R.drawable.jay_z_linkin_park);

add(R.drawable.korn);

add(R.drawable.defense_mechanism);

add(R.drawable.gzorah);

add(R.drawable.defense_mechanism);

add(R.drawable.gzorah);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值