gridview 中的第一项在 AdapterView.OnItemClickListener 中没有变化
First item in gridview does not change in the AdapterView.OnItemClickListener
我有图像的网格视图。单击图像时,我会设置一个可绘制的小复选标记以将其标记为已选中,当单击另一个项目时,我会遍历所有项目并删除复选标记。
问题是我在网格视图中的第一个项目在检查后没有更新。它在检查后根本不做任何事情。所有其他项目都按预期工作 - 单击时会选中它们,单击另一个项目时会取消选中。单击时只有第一个项目保持选中状态,单击其他项目时不会更改。
下面是 onItemClickListener 代码。有任何想法吗?
for (int i = 0; i < shapeIds.length; i++) {
ImageView imageView = (ImageView) adapterView.getItemAtPosition(i);
imageView.setImageDrawable(null); // does not work on item 0
}
Drawable check = VectorDrawableCompat.create(getResources(), R.drawable.check_circle, null);
((ImageView) view).setImageDrawable(check);
编辑:添加更多代码以帮助理解问题。这是我的适配器代码:
public class ImageAdapter extends BaseAdapter {
private Context context;
private ImageView imageView;
private int[] itemIds;
private ImageView[] views;
ImageAdapter(Context c, int[] itemIds) {
context = c;
this.itemIds = itemIds;
views = new ImageView[itemIds.length];
}
@Override
public int getCount() {
return itemIds.length;
}
@Override
public Object getItem(int position) {
return views[position];
}
@Override
public long getItemId(int position) {
return itemIds[position];
}
@Override
public View getView(int position, View convertView, ViewGroup viewGroup) {
imageView = new ImageView(context);
Drawable mainDrawable = VectorDrawableCompat.create(getResources(), itemIds[position], null);
imageView.setBackground(mainDrawable);
views[position] = imageView;
return imageView;
}
}
从 getView()
登录时,您可能已经注意到此方法似乎至少为 position=0 调用了两次。
您正在保留从 getView()
填充的 ImageView
数组,但至少对于 position=0 您不能确定您在那里创建的 ImageView
实际上将被添加到 GridView
。
你能做些什么来解决你的问题?一种选择是将 itemIds 保留为适配器的数据,而不是尝试自己管理 ImageView
。相反,适配器可以像这样跟踪检查的位置:
public class ImageAdapter extends BaseAdapter {
private Context context;
private ImageView imageView;
private int[] itemIds;
private int checkedPosition = -1;
private Drawable check;
ImageAdapter(Context c, int[] itemIds) {
context = c;
check = VectorDrawableCompat.create(context.getResources(), R.drawable.ic_check_circle, null);
this.itemIds = itemIds;
}
public void setCheckedPosition(int checkedPosition){
this.checkedPosition = checkedPosition;
}
@Override
public int getCount() {
return itemIds.length;
}
@Override
public Object getItem(int position) {
return itemIds[position];
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup viewGroup) {
imageView = new ImageView(context);
Drawable mainDrawable = VectorDrawableCompat.create(getResources(), itemIds[position], null);
imageView.setBackground(mainDrawable);
if(checkedPosition == position){
imageView.setImageDrawable(check);
}
else{
imageView.setImageDrawable(null);
}
return imageView;
}
}
顺便说一句,实现 ViewHolder 模式可能是个好主意,但我在这里跳过它以尽可能接近您的代码。
您的 OnItemClickListener 如下所示:
final ImageAdapter adapter = new ImageAdapter(this, shapeIds);
gridView.setAdapter(adapter);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
adapter.setCheckedPosition(position);
adapter.notifyDataSetChanged();
}
});
我有图像的网格视图。单击图像时,我会设置一个可绘制的小复选标记以将其标记为已选中,当单击另一个项目时,我会遍历所有项目并删除复选标记。
问题是我在网格视图中的第一个项目在检查后没有更新。它在检查后根本不做任何事情。所有其他项目都按预期工作 - 单击时会选中它们,单击另一个项目时会取消选中。单击时只有第一个项目保持选中状态,单击其他项目时不会更改。
下面是 onItemClickListener 代码。有任何想法吗?
for (int i = 0; i < shapeIds.length; i++) {
ImageView imageView = (ImageView) adapterView.getItemAtPosition(i);
imageView.setImageDrawable(null); // does not work on item 0
}
Drawable check = VectorDrawableCompat.create(getResources(), R.drawable.check_circle, null);
((ImageView) view).setImageDrawable(check);
编辑:添加更多代码以帮助理解问题。这是我的适配器代码:
public class ImageAdapter extends BaseAdapter {
private Context context;
private ImageView imageView;
private int[] itemIds;
private ImageView[] views;
ImageAdapter(Context c, int[] itemIds) {
context = c;
this.itemIds = itemIds;
views = new ImageView[itemIds.length];
}
@Override
public int getCount() {
return itemIds.length;
}
@Override
public Object getItem(int position) {
return views[position];
}
@Override
public long getItemId(int position) {
return itemIds[position];
}
@Override
public View getView(int position, View convertView, ViewGroup viewGroup) {
imageView = new ImageView(context);
Drawable mainDrawable = VectorDrawableCompat.create(getResources(), itemIds[position], null);
imageView.setBackground(mainDrawable);
views[position] = imageView;
return imageView;
}
}
从 getView()
登录时,您可能已经注意到此方法似乎至少为 position=0 调用了两次。
您正在保留从 getView()
填充的 ImageView
数组,但至少对于 position=0 您不能确定您在那里创建的 ImageView
实际上将被添加到 GridView
。
你能做些什么来解决你的问题?一种选择是将 itemIds 保留为适配器的数据,而不是尝试自己管理 ImageView
。相反,适配器可以像这样跟踪检查的位置:
public class ImageAdapter extends BaseAdapter {
private Context context;
private ImageView imageView;
private int[] itemIds;
private int checkedPosition = -1;
private Drawable check;
ImageAdapter(Context c, int[] itemIds) {
context = c;
check = VectorDrawableCompat.create(context.getResources(), R.drawable.ic_check_circle, null);
this.itemIds = itemIds;
}
public void setCheckedPosition(int checkedPosition){
this.checkedPosition = checkedPosition;
}
@Override
public int getCount() {
return itemIds.length;
}
@Override
public Object getItem(int position) {
return itemIds[position];
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup viewGroup) {
imageView = new ImageView(context);
Drawable mainDrawable = VectorDrawableCompat.create(getResources(), itemIds[position], null);
imageView.setBackground(mainDrawable);
if(checkedPosition == position){
imageView.setImageDrawable(check);
}
else{
imageView.setImageDrawable(null);
}
return imageView;
}
}
顺便说一句,实现 ViewHolder 模式可能是个好主意,但我在这里跳过它以尽可能接近您的代码。
您的 OnItemClickListener 如下所示:
final ImageAdapter adapter = new ImageAdapter(this, shapeIds);
gridView.setAdapter(adapter);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
adapter.setCheckedPosition(position);
adapter.notifyDataSetChanged();
}
});