GridView适配器未检测到最后一个单元格的点击

时间:2014-05-31 18:15:17

标签: android gridview

我有一个以两种模式运行的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;
    }
}

1 个答案:

答案 0 :(得分:1)

这些行:

viewHolder.checkBox.setId(position);
viewHolder.imageView.setId(position);
viewHolder.id = position;
viewHolder.checkBox.setChecked(mThumbSelection[position]);

也应该在convertView != null时执行。

滚动ListViewGridView时,查看屏幕在回收商中的退出位置。每当需要创建新行时,如果有可用的循环视图将被使用。这是为了使滚动更快,因为从头开始创建视图是昂贵的。

问题是,由于您只在创建新视图时设置了这些值,因此第一个重用视图将具有在该视图被回收之前具有的ID 而不是正确的视图。