您的位置:首页 > 移动开发 > Android开发

Android Batch Contextual Actions使用方法

2014-09-08 21:26 162 查看

1. 概述

所谓Batch Contextual Actions,是用于ListView、GridView,以及其他AbsListView子类的一种contextual action mode。

1.1 UI操作步骤

在UI界面上的操作步骤:

首先是长按一个item,此时会进入context mode,然后就可以通过单击继续选择item。
选择action bar上面的某个action;
对所有已选择的items执行这个action处理。

1.2 代码步骤

和上一篇contextual action mode的方法基本一致,如下:

view必须是ListView、GridView,以及其他从AbsListView继承的子类;
定义MultiChoiceModeListener接口的一个实现;
上述view调用setMultiChoiceModeListener()方法,传入参数就是上一步的MultiChoiceModeListener对象;
view调用setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
通常还需要一个对象记录所有已选中的item,作为后续action item操作的数据集合。

2. 示例

这里以ListView为例,有增加分数和减少分数两种action。

2.1 布局文件

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

<!-- hello_batch_contextual_actions.xml -->

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<ListView
android:id="@+id/list_view_id"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>

</LinearLayout>


2.2 上下文菜单/actions

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

<!-- context_menu.xml -->

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

<item
android:id="@+id/add_score"
android:title="@string/add_score"
android:titleCondensed="@string/add"
android:icon="@drawable/ic_launcher"
android:showAsAction="ifRoom|withText"/>

<item
android:id="@+id/minus_score"
android:title="@string/minus_score"
android:titleCondensed="@string/minus"
android:icon="@drawable/ic_launcher"
android:showAsAction="ifRoom|withText"/>

</menu>


2.3 ListView中每个item的布局

<!-- student_item.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >

<TextView
android:id="@+id/student_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:textSize="20sp" />

<TextView
android:id="@+id/student_score"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="20sp" />

</LinearLayout>


2.4 字符串资源

<string name="add_score">Add Score</string>
<string name="add">Add</string>
<string name="minus_score">Minus Score</string>
<string name="minus">Minus</string>


2.5 Java代码

package com.example.hellobatchcontextualactions;

import java.util.ArrayList;
import java.util.HashMap;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.AbsListView.MultiChoiceModeListener;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;

public class MainActivity extends Activity {

protected static final String TAG = "MainActivity";

BaseAdapter adapter = null;
ArrayList<HashMap<String, Object>> selectedStudents = new ArrayList<HashMap<String, Object>>();

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.hello_batch_contextual_actions);

ListView listView = (ListView) this.findViewById(R.id.list_view_id);
setData(listView);

listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {

@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.context_menu, menu);

selectedStudents.clear();

return true;
}

@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
// TODO Auto-generated method stub
return false;
}

@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.add_score:
//mode.setTitle("Add Score");
addSelectedItemsScore();
mode.finish();
return true;

case R.id.minus_score:
//mode.setTitle("Minus Score");
minusSelectedItemsScore();
mode.finish();
return true;

default:
return false;
}
}

@Override
public void onDestroyActionMode(ActionMode mode) {
// TODO Auto-generated method stub

}

@Override
public void onItemCheckedStateChanged(ActionMode mode,
int position, long id, boolean checked) {
Log.d(TAG,
"onItemCheckedStateChanged()[position=" + position
+ ",id=" + id
+ ",checked=" + checked
+ "]");
if (checked) {
selectedStudents.add((HashMap<String, Object>) adapter.getItem(position));
} else {
selectedStudents.remove(adapter.getItem(position));
}
}

});
}

private void setData(ListView listView) {
// each item's layout resource id
int student_item_id = R.layout.student_item;

// columns names
String[] columnNames = new String[] { "name", "score" };

// resource ids
int[] ids = new int[] { R.id.student_name, R.id.student_score };

// the data to be displayed
ArrayList<HashMap<String, Object>> students = new ArrayList<HashMap<String, Object>>();
HashMap<String, Object> map = null;
for (int i = 1; i <= 10; i++) {
map = new HashMap<String, Object>();
map.put(columnNames[0], "student-" + i);
map.put(columnNames[1], String.valueOf(i * 10));
students.add(map);
}

adapter = new SimpleAdapter(this, students, student_item_id,
columnNames, ids);
listView.setAdapter(adapter);

}

private void minusSelectedItemsScore() {
for (HashMap<String, Object> student : selectedStudents) {
updateScore(student, -1);
}

selectedStudents.clear();
adapter.notifyDataSetChanged();
}

private void addSelectedItemsScore() {
for (HashMap<String, Object> student : selectedStudents) {
updateScore(student, 1);
}

selectedStudents.clear();
adapter.notifyDataSetChanged();
}

private void updateScore(HashMap<String, Object> student, int incremental) {
Log.d(TAG, "old: " + student.toString());

String studentName = (String) student.get("name");
String studentScore = (String) student.get("score");
int score = Integer.parseInt(studentScore);

student.put("score", String.valueOf(score + incremental));

Log.d(TAG, "new: " + student.toString());
}

}


2.6 运行效果

日志:

09-08 21:03:33.586: D/MainActivity(3748): onItemCheckedStateChanged()[position=0,id=0,checked=true]
09-08 21:03:37.106: D/MainActivity(3748): onItemCheckedStateChanged()[position=2,id=2,checked=true]
09-08 21:03:38.516: D/MainActivity(3748): onItemCheckedStateChanged()[position=4,id=4,checked=true]
09-08 21:03:39.796: D/MainActivity(3748): onItemCheckedStateChanged()[position=6,id=6,checked=true]
09-08 21:03:40.946: D/MainActivity(3748): onItemCheckedStateChanged()[position=8,id=8,checked=true]
09-08 21:03:44.336: D/MainActivity(3748): old: {score=10, name=student-1}
09-08 21:03:44.336: D/MainActivity(3748): new: {score=11, name=student-1}
09-08 21:03:44.336: D/MainActivity(3748): old: {score=30, name=student-3}
09-08 21:03:44.336: D/MainActivity(3748): new: {score=31, name=student-3}
09-08 21:03:44.336: D/MainActivity(3748): old: {score=50, name=student-5}
09-08 21:03:44.336: D/MainActivity(3748): new: {score=51, name=student-5}
09-08 21:03:44.336: D/MainActivity(3748): old: {score=70, name=student-7}
09-08 21:03:44.336: D/MainActivity(3748): new: {score=71, name=student-7}
09-08 21:03:44.336: D/MainActivity(3748): old: {score=90, name=student-9}
09-08 21:03:44.336: D/MainActivity(3748): new: {score=91, name=student-9}
09-08 21:03:51.526: D/MainActivity(3748): onItemCheckedStateChanged()[position=1,id=1,checked=true]
09-08 21:03:53.376: D/MainActivity(3748): onItemCheckedStateChanged()[position=3,id=3,checked=true]
09-08 21:03:54.446: D/MainActivity(3748): onItemCheckedStateChanged()[position=5,id=5,checked=true]
09-08 21:03:55.676: D/MainActivity(3748): onItemCheckedStateChanged()[position=7,id=7,checked=true]
09-08 21:03:56.906: D/MainActivity(3748): onItemCheckedStateChanged()[position=9,id=9,checked=true]
09-08 21:03:59.276: D/MainActivity(3748): old: {score=20, name=student-2}
09-08 21:03:59.276: D/MainActivity(3748): new: {score=19, name=student-2}
09-08 21:03:59.276: D/MainActivity(3748): old: {score=40, name=student-4}
09-08 21:03:59.276: D/MainActivity(3748): new: {score=39, name=student-4}
09-08 21:03:59.286: D/MainActivity(3748): old: {score=60, name=student-6}
09-08 21:03:59.286: D/MainActivity(3748): new: {score=59, name=student-6}
09-08 21:03:59.286: D/MainActivity(3748): old: {score=80, name=student-8}
09-08 21:03:59.286: D/MainActivity(3748): new: {score=79, name=student-8}
09-08 21:03:59.306: D/MainActivity(3748): old: {score=100, name=student-10}
09-08 21:03:59.306: D/MainActivity(3748): new: {score=99, name=student-10}
09-08 21:04:05.026: D/MainActivity(3748): onItemCheckedStateChanged()[position=0,id=0,checked=true]


UI:



2.7 问题

通过日志,可以看到一个个item被选中。但从UI视觉上,根本无法看出来。因此,应用的易用性存在问题。

解决方法就是ListView中每个item增加一个checkbox或类似的元素,标识出每个元素是否被选中。

3. 增加checkbox

TODO
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: