gpt4 book ai didi

android - 自定义 ListView 适配器,奇怪的 ImageView 行为

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:52:20 27 4
gpt4 key购买 nike

我有一个自定义的 ListView Adapter,我用它为列表创建行。但我的问题是,它似乎并没有将 ImageView 彼此区分开来。当我上下滚动时,它似乎是随机选择 ImageViews 到位。文本信息(从此 fragment 中省略)不会中断。正如人们所期望的那样工作。

下面是我的Adapter的相关方法:

  public View getView( int position, View convertView, ViewGroup parent )
{
View v = convertView;

if( v == null )
{
LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate( R.layout.generic_row, null );
}

// find the image
ImageView favImage = (ImageView)v.findViewById( R.id.toggle_favorite );

// when clicked...
favImage.setOnClickListener( new OnClickListener() {

@Override
public void onClick( View v )
{
// make the gray star a yellow one
int newImage = R.drawable.ic_star_yellow_embossed;
((ImageView)v).setImageBitmap(BitmapFactory.decodeResource(getContext().getResources(), newImage));
}

});

return v;
}

最佳答案

该行为的出现是因为 ListView当您上下滚动列表时回收行 View ,因此您会得到用户操作的行(图像已更改)在图像应该未修改的位置。为避免这种情况,您必须以某种方式保持 ImageView 的状态。对于列表中的每一行,并使用此状态在 getView() 中设置正确的图像方法。因为您没有说明您具体是如何实现适配器的,所以我将向您展示一个简单的示例。

首先,您应该存储 ImageView 的状态.我用了 ArrayList<Boolean>作为自定义适配器的成员,如果这个列表中的位置(对应行在列表中的位置)是false那么图像是默认图像,否则如果它是 true然后用户点击它,我们应该放新图片:

private ArrayList<Boolean> imageStatus = new ArrayList<Boolean>();

在您的自定义适配器构造函数中初始化此列表。例如,如果你在你的适配器中放入了一些东西的列表,那么你应该使你的 imageStatus和那个列表一样大,充满了false (默认/启动状态):

//... initialize the imageStatus, objects is the list on which your adapter is based
for (int i = 0; i < objects.size(); i++) {
imageStatus.add(false);
}

然后在你的getView()方法:

View v = convertView;

if (v == null) {
LayoutInflater vi = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.adapters_adapter_with_images, null);
}

// find the image
ImageView favImage = (ImageView) v
.findViewById(R.id.toggle_favorite);
// Set the image bitmap. If the imageStatus flag for this position is TRUE then we
// show the new image because it was previously clicked by the user
if (imageStatus.get(position)) {
int newImage = R.drawable.ic_star_yellow_embossed;
favImage.setImageBitmap(BitmapFactory.decodeResource(
getContext().getResources(), newImage));
} else {
// If the imageStatus is FALSE then we explicitly set the image
// back to the default because we could be dealing with a
// recycled ImageView that has the new image set(there is no need to set a default drawable in the xml layout)
int newImage = R.drawable.basket_empty; //the default image
favImage.setImageBitmap(BitmapFactory.decodeResource(
getContext().getResources(), newImage));
}
// when clicked... we get the real position of the row and set to TRUE
// that position in the imageStatus flags list. We also call notifyDataSetChanged
//on the adapter object to let it know that something has changed and to update!
favImage.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
Integer realPosition = (Integer) v.getTag(); //get the position from the view's tag
imageStatus.set(realPosition, true); //this position has been clicked be the user
adapter.notifyDataSetChanged(); //notify the adapter
}

});
// set the position to the favImage as a tag, we later retrieve it
// in the onClick method
favImage.setTag(new Integer(position));
return v;

}

如果您不打算动态修改列表(删除/添加行),这应该能很好地工作,否则您还必须注意修改 imageStatus 的列表。以反射(reflect)变化。你没有说你的行数据是什么,另一种方法(如果你打算在用户单击该图像时做某事(除了更改它)是正确的方法)是将图像的状态合并到行的数据模型中。关于此,这里有一些教程:

Android ListView Advanced InteractiveCommonsware-Android Excerpt (交互式行)

关于android - 自定义 ListView 适配器,奇怪的 ImageView 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9754057/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com