展会信息港展会大全

解决Android中使用ListView和CheckBox批量操作时若干问题
来源:互联网   发布日期:2015-11-25 22:35:32   浏览:2609次  

导读:本文可以帮助 完美解决 在Android中使用ListView时批量操作CheckBox出现的各种问题。在Android中使用ListActivity可以很方便的绑定一组数据或者一个查询。但是,使用过程中也会遇到一些问题。在此,我将自己遇......

本文可以帮助 完美解决 在Android中使用ListView时批量操作CheckBox出现的各种问题。

在Android中使用ListActivity可以很方便的绑定一组数据或者一个查询。但是,使用过程中也会遇到一些问题。在此,我将自己遇到的问题以及解决方法记录下来,一方面做一个备忘,同时,也希望有缘人能少走弯路。

问题一: Listview中的Item数目到底是多少

ListView中的Item数目可以使用getCount方法获得,经过验证得到的结果是,其Item数目等于界面上显示的Item数目,这个数目可能小于实际上绑定的数据条目数。

那么,在实际中如果有额外的非绑定数据源的数据需要编辑保存的时候,如何才能保存他们呢?

解决该问题的方法是:自定义ListAdapter,在其中保存额外需要保存的数据。

问题二:在Item中添加CheckBox出现麻烦了

在item中添加Checkbox的时候不小心会遇到麻烦,可能出现的情况是:

(1)Listview不能相应点击事件

(2)Listview点击第一个Item的时候最后一个Item也出现点击事件(反之亦然)

以上两种情况是我实际遇到的bug,经过各种纠结和反复测试,出现问题的原因是CheckBox相应焦点、点击事件的优先级别比Listview要高,所以出现问题。

解决方法如下(和问题一一对应):

(1)将Checkbox设置focusable属性为false

(2)接着将CheckBox设置Clickable属性为false.

以下是本人程序片段,仅供参考:

<!-- ans_list.xml -->

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:paddingLeft="8dp"

android:paddingRight="8dp" >

<TextView

android:id="@+id/ans_title"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_alignParentTop="true"

android:gravity="center"

android:textSize="15sp"

android:textStyle="bold" />

<RelativeLayout

android:id="@+id/ans_foot"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_alignParentBottom="true"

android:paddingLeft="8sp"

android:paddingRight="8sp" >

<CheckBox

android:id="@+id/ans_cbx_select"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignParentRight="true"

android:layout_marginLeft="10sp"

android:checked="false" />

<Button

android:id="@+id/ans_btn_showInMap"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_toLeftOf="@id/ans_cbx_select"

android:text="@string/ans_btn_showInMap" />

</RelativeLayout>

<ListView

android:id="@android:id/list"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:layout_above="@id/ans_foot"

android:layout_below="@id/ans_title"

android:drawSelectorOnTop="false" >

</ListView>

<TextView

android:id="@android:id/empty"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:gravity="center"

android:text="@string/ans_list_empty"

android:textSize="25sp"

android:textStyle="bold" >

</TextView>

</RelativeLayout>

<!-- ans_item.xml -->

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:padding="10sp" >

<CheckBox

android:id="@+id/ans_item_select"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignParentRight="true"

android:focusable="false"

android:clickable="false"

android:checked="false"

android:gravity="center_vertical" />

<RelativeLayout

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_alignParentLeft="true"

>

....

<TextView

android:id="@+id/ans_item_time"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_below="@id/ans_item_locname"

android:layout_toRightOf="@id/a4" />

</RelativeLayout>

</RelativeLayout>

public class AnsList extends ListActivity {

private PoiDbAdapter dba = null;

private Cursor cursor = null;

private ListView listView = null;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.ans_list);

// 初始化标题

...

// 初始化列表

initList();

if (listView == null || listView.getCount() < 1) {

findViewById(R.id.ans_foot).setVisibility(View.GONE);

} else {

initEvents();

}

}

/** 初始化列表 */

private void initList() {

listView = getListView();

dba = new PoiDbAdapter(this);

cursor = dba.selectAnsByQnaire(QNaireBuilder.getQnaire(null)

.getQnaireId());

startManagingCursor(cursor);

// 构造游标适配器

MyCursorAdapter adapter = new MyCursorAdapter(this, R.layout.ans_item,

cursor, new String[] { ARemoteId, ALongi, ALati, ALocName,

ATime }, new int[] { R.id.ans_item_num,

R.id.ans_item_longi, R.id.ans_item_lati,

R.id.ans_item_locname, R.id.ans_item_time });

// 自定义ViewBinder,日期类型的数据需要转换

adapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {

public boolean setViewValue(View view, Cursor cursor,

int columnIndex) {

String text = cursor.getString(columnIndex);

if (cursor.getColumnName(columnIndex).equalsIgnoreCase(ATime)) {

text = TimeTools.formatTime(Long.valueOf(text));

}

if (view instanceof TextView) {

((TextView) view).setText(text);

}

return true;

}

});

setListAdapter(adapter);

}

/** 为按钮和复选框添加事件处理, 为列表添加事件 */

private void initEvents() {

....

((CheckBox) findViewById(R.id.ans_cbx_select))

.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

@Override

public void onCheckedChanged(CompoundButton buttonView,

boolean isChecked) {

selectAllOrNot(isChecked);

}

});

}

...

/** 全选或全部不选 */

protected void selectAllOrNot(boolean isChecked) {

int count = listView.getChildCount();

for (int i = 0; i < count; i++) {

((CheckBox) ((listView.getChildAt(i))

.findViewById(R.id.ans_item_select))).setChecked(isChecked);

}

((MyCursorAdapter) listView.getAdapter()).selectAll(isChecked);

}

...

@Override

protected void onListItemClick(ListView l, View v, int position, long id) {

CheckBox cbx = (CheckBox) v.findViewById(R.id.ans_item_select);

if (cbx != null) {

cbx.toggle();

((MyCursorAdapter) l.getAdapter())

.select(position, cbx.isChecked());

}

}

}

// 自定义ListAdapter

public class MyCursorAdapter extends SimpleCursorAdapter {

private HashMap<Integer, Boolean> isSelected = null;

public MyCursorAdapter(Context context, int layout, Cursor c,

String[] from, int[] to) {

super(context, layout, c, from, to);

isSelected = new HashMap<Integer, Boolean>();

selectAll(false);

}

// ListView加载新的Item的时候会调用这个方法

// 在加载前设置好意境保存好的Checkbox的状态

@Override

public View getView(int position, View convertView, ViewGroup parent) {

convertView = super.getView(position, convertView, parent);

Boolean b = isSelected.get(position);

if (null == b)

b = false;

if (convertView instanceof ViewGroup) {

ViewGroup g = (ViewGroup) convertView;

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

View v = g.getChildAt(i);

if (v instanceof CheckBox) {

((CheckBox) v).setChecked(b);

break;

}

}

}

return convertView;

}

public void select(int postion, boolean isChecked) {

isSelected.put(postion, isChecked);

}

public void selectAll(boolean isChecked) {

int a = this.getCount();

for (int b = 0; b < a; b++) {

select(b, isChecked);

}

}

}

经过折腾之后,终于顺利通过调试,可以轻松实现全选批量操作

赞助本站

人工智能实验室

相关热词: 批量操作 ListView CheckBox

AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港