我几天来一直在寻找这个问题的解决方案。
我正在尝试创建一个自定义ListView列表项,可以选择进行批量编辑。这类似于列出收件箱中的电子邮件的Gmail应用程序,允许您为操作选择一组电子邮件(删除,移动等)。
我的要求是:
我尝试将自己的复选框添加到我的视图中,并为其设置一个OnClickListener,将列表项标记为选中/未选中,但这对我来说并不适用。
感谢任何帮助;即使它只让我90%的路程。
请记住,我正在努力让它在Android 2.1及更高版本上运行。
谢谢
答案 0 :(得分:6)
这是我为实现自己的自定义列表视图而阅读的资源。这对我真的很有帮助。我认为您需要在list_item.xml文件中添加一个复选框并更改布局属性。
您还需要在自定义适配器内的CheckBox对象onCheckedChanged上添加一个侦听器。
以下是自定义适配器的示例代码;
public class EntryAdapter extends ArrayAdapter<Entry> {
private Activity context;
private LayoutInflater inflater;
private ArrayList<Entry> entries;
public EntryAdapter(Activity context, ArrayList<Entry> objects) {
super(context, R.layout.entry_item, objects);
// TODO Auto-generated constructor stub
this.context = context;
this.entries = objects;
}
public View getView (int position, View convertView, ViewGroup parent)
{
View viewRow = convertView;
if(viewRow == null)
{
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
viewRow = inflater.inflate(R.layout.entry_item , null, true);
}
Entry e = entries.get(position);
if(e != null)
{
TextView aka = (TextView) viewRow.findViewById(R.id.authorTextView);
TextView content = (TextView) viewRow.findViewById(R.id.entryContentTextView);
if(aka != null && content != null){
aka.setText(e.getAka());
content.setText(e.getContent());
}
}
return viewRow;
}
}
在此代码中,没有事件侦听器。你首先应该做的是添加定义一个类似于布尔的arraylist
ArrayList<boolean> selectedItems;
之后,在getView方法中你应该添加以下内容;
CheckBox cb = (CheckBox) findViewById(R.id.checkBoxId);
之后,你应该在getView()方法中添加onCheckStateChanged监听器
cb.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
if ( isChecked )
{
// find out the item is selected or not and add to selected arraylist by using the position of the element
}
}
});
最后,你应该有getSelectedMethod,它返回所选项目的arraylist相对于他们的位置。
希望我理解这个问题,对你有所帮助。
答案 1 :(得分:3)
所以我相信我已经解决了我面临的主要问题。
我相信我遇到的问题是我的视图并不代表ListView的状态。在拉门里;我认为需要一个复选框来设置列表项是否被选中(这是我的Web开发人员)。但是,无论您是否有一个视图(CheckBox)来表示,ListView都会保持自己检查的状态,而不是什么。
布局/ list_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/linearLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ProgressBar
android:id="@+id/progressBar1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dip" />
<LinearLayout
android:id="@+id/linearLayout2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Line 1"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Line 2" />
</LinearLayout>
<CheckBox
android:id="@+id/checkBox1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false"
android:focusable="false"
android:visibility="gone" />
</LinearLayout>
菜单/ menu.xml文件
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/edit_menu_item"
android:title="KAMEHAMEHA!!!!!"/>
</menu>
菜单/ edit.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/commit_menu_item"
android:title="Commit"/>
<item
android:id="@+id/cancel_menu_item"
android:title="Cancel"/>
</menu>
ListViewTestActivity.java
package com.loesak.listviewtest;
import android.app.ListActivity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class ListViewTestActivity extends ListActivity {
private static final String[] GENRES = new String[] {
"Action", "Adventure", "Animation", "Children", "Comedy", "Documentary", "Drama",
"Foreign", "History", "Independent", "Romance", "Sci-Fi", "Television", "Thriller"
};
private ListView listView = null;
private MyArrayAdapter myArrayAdapter = null;
private boolean editMode = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.listView = getListView();
this.myArrayAdapter = new MyArrayAdapter(this, GENRES);
this.setListAdapter(this.myArrayAdapter);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
menu.clear();
MenuInflater inflater = this.getMenuInflater();
if(!this.editMode) {
inflater.inflate(R.menu.menu, menu);
} else {
inflater.inflate(R.menu.edit, menu);
}
return super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == R.id.edit_menu_item) {
Toast.makeText(this, "entering edit mode", Toast.LENGTH_SHORT).show();
this.editMode = true;
this.listView.setItemsCanFocus(false);
this.listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
this.myArrayAdapter.setEditMode(editMode);
} else if(item.getItemId() == R.id.commit_menu_item
|| item.getItemId() == R.id.cancel_menu_item) {
if(item.getItemId() == R.id.commit_menu_item) {
Toast.makeText(this, "committing changes", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "leaving edit mode", Toast.LENGTH_SHORT).show();
}
this.editMode = false;
this.listView.setItemsCanFocus(true);
this.listView.setChoiceMode(ListView.CHOICE_MODE_NONE);
this.listView.clearChoices();
this.myArrayAdapter.setEditMode(editMode);
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
if(!this.editMode) {
Toast.makeText(this, "list item selected at position " + position, Toast.LENGTH_SHORT).show();
} else {
String str = "";
SparseBooleanArray wtfit = l.getCheckedItemPositions();
for(int i = 0; i < GENRES.length; i++) {
if(wtfit.get(i)) {
str += i + ", ";
}
}
Toast.makeText(this, "Selected item positions: " + str, Toast.LENGTH_SHORT).show();
}
super.onListItemClick(l, v, position, id);
}
class MyArrayAdapter extends ArrayAdapter<String> {
private Context context;
private String[] entires;
private boolean editMode = false;
public MyArrayAdapter(Context context, String[] entries) {
super(context, R.layout.list_item, entries);
this.context = context;
this.entires = entries;
}
@Override
public View getView(final int position, View view, ViewGroup parent) {
final ListView listView = (ListView) parent;
final ViewHolder viewHolder;
if(view == null) {
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = layoutInflater.inflate(R.layout.list_item, null, true);
viewHolder = new ViewHolder();
viewHolder.text1 = (TextView) view.findViewById(R.id.textView1);
viewHolder.text2 = (TextView) view.findViewById(R.id.textView2);
viewHolder.checkbox1 = (CheckBox) view.findViewById(R.id.checkBox1);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
viewHolder.text1.setText(this.entires[position] + "_1");
viewHolder.text2.setText(this.entires[position] + "_2");
viewHolder.checkbox1.setChecked(listView.isItemChecked(position));
if(this.editMode) {
viewHolder.checkbox1.setVisibility(View.VISIBLE);
} else {
viewHolder.checkbox1.setVisibility(View.GONE);
}
return view;
}
public void setEditMode(boolean editMode) {
this.editMode = editMode;
this.notifyDataSetChanged();
}
class ViewHolder {
TextView text1;
TextView text2;
CheckBox checkbox1;
}
}
}
要使复选框反映列表项的实际选定模式:
viewHolder.checkbox1.setChecked(listView.isItemChecked(position));
就是这样。一旦你知道这一切是如何运作的,那就很明显了。太糟糕了我花了很长时间才弄明白。有时我觉得android编程有时候太复杂了。
我现在唯一的问题是,当单击列表项时,ListView项总是被重绘。这对包含来自文件的异步加载图像的列表项目造成了严重破坏。希望当我加强我的代码部分的性能时,这将消失。
答案 2 :(得分:0)
如同之前的帖子一样:
每当你想用ListView中的视图进行处理时 需要创建一个可以处理逻辑的自定义适配器 实现并在必要时将该信息传递给视图。
这是您需要的起点。在构建视图时,必须明确定义每一行。单击特定视图时,将处理该特定行。您可以做的一件事是在单击编辑按钮时,您将获取该行中的所有数据并将其转换为另一个看似可编辑的视图。然后在确认中,您将更新该行并将其转换回原始视图。