我有一个以两种模式运行的GridView适配器。在一种模式中,当单击一个单元格时,它将打开一个活动,其中显示了单元格中显示的内容。在另一种模式SelectMode中,每个单元格中都有一个复选框,单击单击框后,复选框将被设置或清除,并且活动标题栏中会显示许多选定的单元格。
当我切换到选择模式时,网格中的最后一个单元格似乎没有收到点击。我说“似乎”的原因是,当我单击其他单元格时,标题栏中显示的所选计数反映了最后一个单元格的选择,即使单击最后一个单元格时从未调用OnClick事件,并且复选框是从未设置在最后一个单元格中。网格视图中的单元格数量是可变的,但它始终是出现此问题的最后一个单元格。
任何指针都将非常感激。下面是备份GridView的BaseAdapter的代码,我猜这个问题出在getView()的某个地方。
谢谢你, 加里
private class ImageAdapter extends BaseAdapter {
private int mItemHeight = 0;
private int mNumColumns = 0;
private GridView.LayoutParams mImageViewLayoutParams;
private LayoutInflater mInflater;
public ImageAdapter(Context context) {
super();
mImageViewLayoutParams = new GridView.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
mInflater = (LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return mFloomitApp.GetPhotoCount();
}
@Override
public Object getItem(int position) {
return mFloomitApp.GetThumbUrl(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getViewTypeCount() {
return 1;
}
@Override
public int getItemViewType(int position) {
return 0;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public View getView(int position, View convertView, ViewGroup container) {
final ViewHolder viewHolder;
if (convertView == null) { // if it's not recycled, instantiate and initialize
viewHolder = new ViewHolder();
convertView = mInflater.inflate(R.layout.image_grid_item, null);
viewHolder.imageView = (RecyclingImageView)convertView.findViewById(R.id.image_grid_item_thumb_image);
viewHolder.imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
viewHolder.checkBox = (CheckBox)convertView.findViewById(R.id.image_grid_item_check_box);
viewHolder.checkBox.setBackgroundColor(Color.WHITE);
viewHolder.checkBox.setId(position);
viewHolder.imageView.setId(position);
viewHolder.id = position;
viewHolder.checkBox.setChecked(mThumbSelection[position]);
viewHolder.checkBox.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
CheckBox checkBox = (CheckBox)v;
int id = checkBox.getId();
mPrevSelectCount = mSelectCount;
if (mThumbSelection[id]) {
checkBox.setChecked(false);
mThumbSelection[id] = false;
if (mSelectCount > 0) {
mSelectCount--;
}
} else {
checkBox.setChecked(true);
mThumbSelection[id] = true;
mSelectCount++;
}
SelectMode(mSelectMode);
}
});
viewHolder.imageView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
int id = v.getId();
if (mSelectMode) {
CheckBox checkBox = viewHolder.checkBox;
if (mThumbSelection[id]) {
checkBox.setChecked(false);
mThumbSelection[id] = false;
if (mSelectCount > 0) {
mSelectCount--;
}
} else {
checkBox.setChecked(true);
mThumbSelection[id] = true;
mSelectCount++;
}
SelectMode(mSelectMode);
} else {
final Intent intent = new Intent(getActivity(), ImageDetailActivity.class);
intent.putExtra(ImageDetailActivity.EXTRA_IMAGE, (int) id);
startActivityForResult(intent, FloomitGlobals.FLOOMIT_PHOTO_DELETE_REQ_CODE);
}
}
});
convertView.setLayoutParams(mImageViewLayoutParams);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder)convertView.getTag();
}
if (mSelectMode) {
viewHolder.checkBox.setVisibility(CheckBox.VISIBLE);
} else {
viewHolder.checkBox.setVisibility(CheckBox.INVISIBLE);
}
if (convertView.getLayoutParams().height != mItemHeight) {
convertView.setLayoutParams(mImageViewLayoutParams);
}
mThumbFetcher.loadImage(getItem(position), viewHolder.imageView);
return convertView;
}
public void setItemHeight(int height) {
if (height == mItemHeight) {
return;
}
mItemHeight = height;
mImageViewLayoutParams =
new GridView.LayoutParams(LayoutParams.MATCH_PARENT, mItemHeight);
mThumbFetcher.setImageSize(height);
notifyDataSetChanged();
}
public void setNumColumns(int numColumns) {
mNumColumns = numColumns;
}
public int getNumColumns() {
return mNumColumns;
}
class ViewHolder {
RecyclingImageView imageView;
CheckBox checkBox;
int id;
}
}
答案 0 :(得分:1)
这些行:
viewHolder.checkBox.setId(position);
viewHolder.imageView.setId(position);
viewHolder.id = position;
viewHolder.checkBox.setChecked(mThumbSelection[position]);
也应该在convertView != null
时执行。
滚动ListView
或GridView
时,查看屏幕在回收商中的退出位置。每当需要创建新行时,如果有可用的循环视图将被使用。这是为了使滚动更快,因为从头开始创建视图是昂贵的。
问题是,由于您只在创建新视图时设置了这些值,因此第一个重用视图将具有在该视图被回收之前具有的ID 而不是正确的视图。