我想创建一个视图,我可以从listview中选择多个项目,也可以并排更改所选列表项目的颜色并将该项目保存到我的arraylist中。我的列表如下所示:
但是当我以前滚动它时......它向我展示了另外一个项目,即使我没有选择它:
但我希望只有那个列表项颜色应该改变我点击的位置......
我使用的代码为:
private class ItemsAdapter extends ArrayAdapter<String> {
List<String> items;
Context context;
private LayoutInflater inflater;
public ItemsAdapter(Context context, List<String> part_array_list) {
super( context, R.layout.part_list, R.id.label,part_array_list );
inflater = LayoutInflater.from(context) ;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView textView ;
String item = (String) this.getItem( position );
if ( convertView == null ) {
convertView = inflater.inflate(R.layout.part_list, null);
// Find the child views.
textView = (TextView) convertView.findViewById( R.id.label );
// Optimization: Tag the row with it's child views, so we don't have to
// call findViewById() later when we reuse the row.
convertView.setTag( new ListViewHolder(textView) );
}
// Reuse existing row view
else {
// Because we use a ViewHolder, we avoid having to call findViewById().
ListViewHolder viewHolder = (ListViewHolder) convertView.getTag();
textView = viewHolder.getTextView() ;
}
textView.setText( part_array_list.get(position) );
return convertView;
}
}
/** Holds child views for one row. */
private class ListViewHolder {
private TextView textView ;
public ListViewHolder() {}
public ListViewHolder( TextView textView ) {
this.textView = textView ;
}
public TextView getTextView() {
return textView;
}
public void setTextView(TextView textView) {
this.textView = textView;
}
}
并且在OnCreate()方法中,
final ArrayAdapter<String> part_list_adapter=new ItemsAdapter(AssetSearch.this, part_array_list);
//PartNumber_List.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
PartNumber_List.setAdapter(part_list_adapter);
PartNumber_List.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View v, int position,
long id) {
ListViewHolder viewHolder = (ListViewHolder) v.getTag();
viewHolder.getTextView().setBackgroundColor(R.color.result_image_border);
String item=(String) part_list_adapter.getItem((int) id);
});
答案 0 :(得分:10)
这里的问题是您正在为视图设置背景颜色,然后在滚动时,由于使用convertView
,您最终会重复使用该视图。这正是你应该做的,在那里做得很好。
但是,当然,这意味着列表项在不应该被选中时被选中。要解决此问题,您的getView()
方法需要将背景颜色重置为其默认值。我不知道最初的颜色是什么,但我认为它是透明的。所以你会把:
textView.setBackgroundColor(android.R.color.transparent);
所以现在您将背景颜色设置为默认值,但如果您从所选项目滚动,然后返回到它,它将具有透明背景而不是所选背景。要解决此问题,请在适配器类中放置ArrayList
Integer
个值。单击某个项目并触发onItemClick()
时,将项目位置添加到ArrayList
。例如,假设你有:
public ArrayList<Integer> selectedIds = new ArrayList<Integer>();
适配器类中的。然后,您的onItemClick
方法将如下所示:
@Override
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
ArrayList<Integer> selectedIds = ((ItemsAdapter) parent).selectedIds;
Integer pos = new Integer(position);
if(selectedIds.contains(pos) {
selectedIds.remove(pos);
}
else {
selectedIds.add(pos);
}
parent.notifyDataChanged();
}
最后,在您的getView()
方法中,添加以下行:
textView.setBackground(selectedIds.contains(position) ? R.color.result_image_border : androi.R.color.transparent);
答案 1 :(得分:3)
我也遇到过这个问题,并发现它是因为回收视图。如果我记得正确的设置,这将删除回收并解决问题,但这不是最好的选择。
@Override
public int getItemViewType(int position) {
return IGNORE_ITEM_VIEW_TYPE;
}
答案 2 :(得分:1)
跟踪活动中listView中选择的项目。在适配器的getView中,检查位置是否等于列表视图中的选定位置,以及视图中的setBackgroundColor。这将有效。
答案 3 :(得分:1)
无论你在itemClick监听器中尝试使用ConvertView,它都会反映在其他类中,为了避免你需要为相应的视图持有者设置背景,我会显示一些对我来说很好的样本,
public View getView(final int position, View convertView, ViewGroup parent) {
System.gc();
final ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.albumlist, null);
holder = new ViewHolder();
holder.albumName = (TextView) convertView.findViewById(R.id.albumDetails);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
holder.albumName.setText(albumData[position][0]);
holder.albumName.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
holder.albumName.setBackgroundColor(R.color.black);
}});
return convertView;
}
class ViewHolder {
TextView albumName;
}
样本o / p
答案 4 :(得分:0)
您必须在单击列表中的任何列表项时设置标记,并选中此标志以确定在适配器的getView()方法中是否已单击该项目的天气。
答案 5 :(得分:0)
关于@JasonRobinson给出的答案的更正:
if(selectedIds.contains(pos) {
selectedIds.remove(pos); -> **selectedIds.remove(selectedIds.indexOf(pos));**
}
else {
selectedIds.add(pos);
}
答案 6 :(得分:0)
来自 Jason Robinson 的解决方案(想法)很好,但是有错误!你不能通过它的值来删除ArrayList中的项目!!!
方法ArrayList.remove(int)将item的索引作为parametr!
如果要使用ArrayList<
,则需要找到要删除的索引项。例如:Integer
>
Integer
或使用方法private int getIndex(int value) {
int index = -1;
for(int i=0; i<selectedIds.size(); i++) {
if(selectedIds.get(i)==value) {
index = i;
break;
}
}
return index;
}
获取索引。
现在,如何从FragmenList或ListActivity引用您的适配器。只需使用类变量:
ArrayList.indexOf(Object)