在上周,我只是试图解决这个问题。看到每个类似的问题,我不知道为什么,解决方案不适合我。 我有一个列表视图,每个项目都有一个图像视图。单击图像视图时,我想更改图像资源。好。全部完成。但滚动时,图像资源会发生变化。 我的完整代码是:
public class CustomBaseAdapter extends BaseAdapter {
Context context;
ArrayList<String> items;
public CustomBaseAdapter(Context context,ArrayList<String> items){
this.context = context;
this.items = items;
}
private class ViewHolder{
TextView titr;
ImageView image;
}
@Override
public int getCount() {
return items.size();
}
@Override
public Object getItem(int position) {
return items.get(position);
}
@Override
public long getItemId(int position) {
return items.hashCode();
}
@Override
public View getView(int position, View view, ViewGroup parent) {
View vi = view;
final ViewHolder holder ;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if(view==null){
vi = inflater.inflate(R.layout.customlistitem,null);
holder = new ViewHolder();
holder.titr = (TextView) vi.findViewById(R.id.listtext);
holder.image = (ImageView) vi.findViewById(R.id.listimg);
holder.image.setTag(position);
vi.setTag(holder);
}
else{
holder = (ViewHolder) vi.getTag();
}
holder.titr.setText(items.get(position));
holder.image.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
v.setBackgroundResource(R.drawable.fav_ic);
}
});
return vi;
}
}
我哪里有错误?
答案 0 :(得分:6)
你必须在holder中使用一个布尔值来检查你的背景图像是否为特定行设置。
支架
private class ViewHolder{
TextView titr;
ImageView image;
boolean isSet;
}
设置图片
holder.image.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
v.setBackgroundResource(R.drawable.fav_ic);
holder.isSet = true
}
});
if(holder.isSet)
{
holder.image.setBackgroundResource(R.drawable.fav_ic);
}
else{
holder.image.setBackgroundResource(no image or other image);
}
希望这会有所帮助。
答案 1 :(得分:2)
这是因为当您滚动listview时,android系统始终会创建新行并销毁不可见的行。你需要修改getView(),如下所示,一切都会好的:
@Override
public View getView(int position, View view, ViewGroup parent) {
View vi = view;
final ViewHolder holder ;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
if(view==null){
vi = inflater.inflate(R.layout.customlistitem,null);
holder = new ViewHolder();
holder.titr = (TextView) vi.findViewById(R.id.listtext);
holder.image = (ImageView) vi.findViewById(R.id.listimg);
holder.image.setTag(position);
vi.setTag(holder);
}
else{
holder = (ViewHolder) vi.getTag();
}
holder.titr.setText(items.get(position));
if(sp.getBoolean("position="+position, false)){
v.setBackgroundResource(R.drawable.fav_ic);
}
holder.image.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
v.setBackgroundResource(R.drawable.fav_ic);
SharedPreferences.Editor edit = sp.edit();
edit.putBoolean("position="+position, true);
edit.commit();
}
});
return vi;
}
答案 2 :(得分:2)
试试这个,
public class CustomBaseAdapter extends BaseAdapter {
Context context;
ArrayList<Items> items;
public CustomBaseAdapter(Context context,ArrayList<Items> items){
this.context = context;
this.items = items;
}
private class ViewHolder{
TextView titr;
ImageView image;
}
@Override
public int getCount() {
return items.size();
}
@Override
public Items getItem(int position) {
return items.get(position);
}
@Override
public long getItemId(int position) {
return items.hashCode();
}
@Override
public View getView(int position, View view, ViewGroup parent) {
View vi = view;
final ViewHolder holder ;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if(view==null){
vi = inflater.inflate(R.layout.customlistitem,null);
holder = new ViewHolder();
holder.titr = (TextView) vi.findViewById(R.id.listtext);
holder.image = (ImageView) vi.findViewById(R.id.listimg);
holder.image.setTag(position);
vi.setTag(holder);
}
else{
holder = (ViewHolder) vi.getTag();
}
holder.titr.setText(items.get(position).getStrTxt());
holder.image.setImageResource(items.get(position).getDrawableImage());
holder.image.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
items.set(position,new Items(R.drawable.fav_ic));
notifyDataSetChanged();
}
});
return vi;
}
}
添加模型类:
public class Items {
int drawableImage;
String strTxt;
public Items(int drawableImage) {
this.drawableImage = drawableImage;
}
public int getDrawableImage() {
return drawableImage;
}
public void setDrawableImage(int drawableImage) {
this.drawableImage = drawableImage;
}
public String getStrTxt() {
return strTxt;
}
public void setStrTxt(String strTxt) {
this.strTxt = strTxt;
}
}
答案 3 :(得分:1)
你应该在构造函数中定义layoutInflater,因为getView()调用每一行,所以如果你在getView()中定义layoutInflater,那么LayoutInflater会为每一行反复定义。
答案 4 :(得分:1)
是的,这个问题总是出现在ListView
中,因为android总是在其中销毁并重新创建行。
您有两种选择:
首先,修改您的适配器以保存ListView
中每一行的状态,并在显示该行之前检查此状态。
第二一,我推荐了这个并在我的代码中使用它,你可以使用RecyclerView
,这个问题不会发生。