为什么要更改设置布局参数的位置,以解决我的问题" OnClickListener不适用于GridView中的第一项"问题?

时间:2013-12-07 03:58:40

标签: android gridview onclicklistener

我正在使用GridView来显示一些图像而我遇到了问题,因为onClickListener不能用于第一张图像。我在SO处发现了一些其他问题同样的问题,但我不喜欢他们的“正确答案”,因为他们中的大多数采用相同的方法:

基本上,每次调用getview时都要实例化视图。这对于性能很糟糕,并且它们可能会在许多设备中面临内存不足的问题。

就我而言,我在GridView中显示资产文件夹中子文件夹内的图像。

我的原始代码带有“第一项”问题(实际上,我的原始代码实现了视图模式,但这个更简单并面临同样的问题):

    @Override
public View getView(int position, View convertView, ViewGroup parent) {
    ImageView imageView;

    if (convertView == null) {
        imageView = new ImageView(_activity);

    } else {
        imageView = (ImageView) convertView;
    }

    // get screen dimensions
    AssetManager assetManager = _activity.getAssets();
    InputStream assetIn = null;
    try {
        assetIn = assetManager.open(_assets_subdir + File.separator + _filePaths.get(position));
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    Bitmap image = BitmapFactory.decodeStream(assetIn);
    imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
    imageView.setLayoutParams(new GridView.LayoutParams(imageWidth, imageWidth));
    imageView.setImageBitmap(image);

    // image view click listener
    imageView.setOnClickListener(new OnImageClickListener(position));

    return imageView;

}

我的最终解决问题的代码:

    @Override
public View getView(int position, View convertView, ViewGroup parent) {
    ImageView imageView;

    if (convertView == null) {
        imageView = new ImageView(_activity);
        imageView.setLayoutParams(new GridView.LayoutParams(imageWidth, imageWidth));

    } else {
        imageView = (ImageView) convertView;
    }

    // get screen dimensions
    AssetManager assetManager = _activity.getAssets();
    InputStream assetIn = null;
    try {
        assetIn = assetManager.open(_assets_subdir + File.separator + _filePaths.get(position));
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    Bitmap image = BitmapFactory.decodeStream(assetIn);
    imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
    imageView.setImageBitmap(image);

    // image view click listener
    imageView.setOnClickListener(new OnImageClickListener(position));

    return imageView;

}

移动代码imageView.setLayoutParams(new GridView.LayoutParams(imageWidth, imageWidth));解决了这个问题。

但为什么呢?我不确定。

我在某处(在SO中)读到它可能正在发生,因为尝试访问尚未膨胀的视图,并且用户建议使用getViewTreeObserver(),但我尝试了这种方法并且无法修复问题。

所以,我决定对代码进行试错,看看瓶颈在哪里,找到了给定的解决方案。

任何人都知道为什么解决这个问题?

2 个答案:

答案 0 :(得分:1)

GridView从AbsListView扩展 - > GridView.LayoutParams实际上是AbsListView.LayoutParams,它包含一些关于视图类型的状态数据以及它是否被回收。

每次调用getView时初始化一组新的布局参数(而不仅仅是在重新创建视图时),你丢失了这个状态数据。

我(目前)不确定为什么它只会导致网格中第一个项目出现问题。

答案 1 :(得分:0)

您的GridView只有一个ImageView?为什么不使用setOnItemClickListener代替OnItemClickListener

像这样,在Activity

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // ...
    gridView.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View v,
                    int position, long id) {
                    // here you have what you want ...
            }
    });
}