0

在 onListItemClick 我想改变点击的项目背景,这是我的代码:

public void onListItemClick(ListView parent, View v, int position, long id){

    if (position != previous_position){
        v.setBackgroundResource(R.drawable.category_clicked_item_bg);
        if (previous_category != null)
            previous_category.setBackgroundResource(R.drawable.category_item_bg);
        previous_category = v;
        previous_position = position;
    }
}

previous_category 和 previous_position 是受保护的变量。

问题是,在项目单击列表中的多个项目被突出显示(更具体地说是 1 或 2)。在列表中有 20 行,如果我点击中间的一行,只有一个会突出显示,如果我点击开头或结尾的任何一行,另一侧的另一行会以间隔 13 行突出显示(这可能是为什么按中间行不要'不要突出第二个)。

我需要列表仅突出显示单击的一行,有什么问题?

附加代码

如果这有帮助,这里还有 ListView 适配器类:

package domehotel.guestbook.page.category;

import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import domehotel.guestbook.R;

public class CategoryAdapter extends ArrayAdapter<CategoryItem>{

Context context; 
int layoutResourceId;    
CategoryItem data[] = null;

public CategoryAdapter(Context context, int layoutResourceId, CategoryItem[] data) {
    super(context, layoutResourceId, data);
    this.layoutResourceId = layoutResourceId;
    this.context = context;
    this.data = data;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View row = convertView;
    CategoryHolder holder = null;

    if(row == null)
    {
        LayoutInflater inflater = ((Activity)context).getLayoutInflater();
        row = inflater.inflate(layoutResourceId, parent, false);

        holder = new CategoryHolder();
        holder.category_name = (TextView)row.findViewById(R.id.category_name);

        row.setTag(holder);
    }
    else
    {
        holder = (CategoryHolder)row.getTag();
    }

    CategoryItem category = data[position];
    holder.category_name.setText(category.category_name);

    return row;
}

static class CategoryHolder
{
    TextView category_name;
}
}
4

3 回答 3

1

由于 ListView 行视图对象每个都被重复用于多行,因此保留有关行视图中哪一行处于活动状态的信息并不是一个好主意,最好将此信息保留在适配器中(在我的情况下为 CategoryAdapter)。CategoryItem 类型的数据数组保存以下类的对象:

public class CategoryItem {

    public String category_name;
    public Boolean is_active = false;

    public CategoryItem(){
        super();
    }

    public CategoryItem(String category_name){
        super();
        this.category_name = category_name.toUpperCase();
    }
}

适配器在 onView 方法中重绘视图项时,检查当前行是否处于活动状态:

if (category.is_active)
    row.setBackgroundResource(activeBgDrawable);
else
    row.setBackgroundResource(inactiveBgDrawable);

因此,当我单击一个项目时,我将 CategoryItem is_active 属性设置为 true,而之前单击的 is_active 属性设置为 false:

if (position != previous_position){
    CategoryAdapter adapter = (CategoryAdapter)parent.getAdapter();
    CategoryItem current_item = adapter.getItem(position);
    current_item.is_active = true;
    if (previous_position != -1){
        CategoryItem previous_item = adapter.getItem(previous_position);
                    previous_item.is_active = false;
        }
    previous_position = position;
    adapter.notifyDataSetChanged();
}

为什么设置视图对象背景不起作用?如果我的 ListView 包含的 ListView 项目比 ListView 可以显示的要多,则列表将变为可滚动的,例如,如果我向下滚动 ListView,那么当上面的项目滑出可见部分时,该行的 ListView 项目 View 对象将被重用于将出现在底部的下一行。因此,如果上面一行是我会更改其 View 对象背景的那一行,那么当它消失时,底行将用上面的 View 对象及其背景重绘,这就是为什么我有时有两个彩色行的原因。

于 2012-08-24T12:14:55.420 回答
0

实际上,您正在重用视图。getView 将名为 convertView 的视图作为第二个参数。ListView 使用旧的 View 项目(如果有的话)调用此方法,该项目已实例化(膨胀)但目前不显示。你的冰毒。onListItemClick 现在设置这些视图之一的背景,但此视图稍后将被重用于另一行,而不重置它的背景。

一个可能的解决方案:

  1. 点击监听器应该只为某处点击位置存储背景颜色或点击标志,然后要求有问题的视图(行)重新渲染(它也可以保存状态,然后直接设置背景)。

  2. getView(..) 方法应始终根据为其位置保存的颜色/状态设置视图的背景颜色。为未标记为已单击的位置设置正常背景,或为单击侦听器标记为已单击的位置设置另一个背景。

于 2012-08-24T10:46:39.260 回答
0

在 OnItemClick 中尝试以下代码

public void onListItemClick(ListView parent, View v, int position, long id){

if (position != previous_position){
    v.setBackgroundResource(R.drawable.category_clicked_item_bg);   
    Object view = parent.getTag();
    if(view!=null){
       // typecasting the Object to View
       ((View)view).setBackgroundResource(R.drawable.category_item_bg);
    }
    previous_position = position;
    parent.setTag(v);
}
}

我希望这能解决你的问题。

于 2012-08-24T10:46:42.860 回答