在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;
}
}
答案 0 :(得分:1)
由于ListView行View对象每个都重复使用多行,因此最好保留有关哪一行在行View中处于活动状态的信息,更好的办法是将此信息保存在Adapter中(在我的例子中为CategoryAdapter)。 data 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();
}
为什么设置View对象背景不起作用?如果我的ListView项目包含的ListView项目多于ListView可以显示的内容,则列表将变为可滚动,例如,如果我向下滚动ListView,那么当上面的项目将滑出可见部分时,ListView项目此行的View对象将重复用于下一行,它将出现在底部。所以,如果上面的行是View对象背景我会改变的那个,那么当它会消失的时候,底部的行将重新绘制上面的View对象及其背景,这就是为什么我有时会有两个彩色的行。 / p>
答案 1 :(得分:0)
事实上,你正在重复使用观点。 getView将名为convertView的视图作为第二个参数。 ListView使用旧的View项(如果有的话)调用此方法,该项被实例化(膨胀)但此时不显示。你的方法。 onListItemClick现在设置其中一个视图的背景,但此视图稍后将重新用于另一行,而不会重置它的背景。
可能的解决方案:
点击监听器应该只为某个点击的位置存储背景颜色或点击的标志,然后让问题的视图(行)重新呈现(它还可以保存状态,然后直接设置背景) )。
getView(..)方法应始终根据其位置保存的颜色/状态设置视图的背景颜色。为未标记为已点击的位置设置正常背景,或为标记为点击侦听器点击的位置设置另一个背景。
答案 2 :(得分: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);
}
}
我希望这能解决你的问题。