【问题标题】:using BaseAdapter o back the GridView使用 BaseAdapter 或返回 GridView
【发布时间】:2013-05-06 06:30:54
【问题描述】:

我尝试在开源项目之上构建我的应用程序。 基本功能是使用 GridView 显示几个图像。 下面是代码sn-p。注释行是原始代码。在原始代码中,Images.imageThumbUrls 是 url 的字符串数组,大小 (Images.imageThumbUrls.length) 为 99。 我想用我自己的版本替换原始网址,我做到了。但是有一个错误。请查看日志。

根据日志,getView 的限制似乎是 99(原始代码)。除了换getCount,我还有什么需要做的吗?

createView 方法中:

        mGridView.getViewTreeObserver().addOnGlobalLayoutListener(
            new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    if (mAdapter.getNumColumns() == 0) {
                        final int numColumns = (int) Math.floor(
                                mGridView.getWidth() / (mImageThumbSize + mImageThumbSpacing));
                        if (numColumns > 0) {
                            final int columnWidth =
                                    (mGridView.getWidth() / numColumns) - mImageThumbSpacing;
                            mAdapter.setNumColumns(numColumns);
                            mAdapter.setItemHeight(columnWidth);
                            if (BuildConfig.DEBUG) {
                                Log.d(TAG, "onCreateView - numColumns set to " + numColumns);
                            }
                        }
                    }
                }
            });

ImageAdapter 类:

private class ImageAdapter extends BaseAdapter {        
public int getCount() {
        //return Images.imageThumbUrls.length + mNumColumns;
        return DataStore.photosInfoOfTag.total + mNumColumns;
}
    @Override
    public View getView(int position, View convertView, ViewGroup container) {
        // First check if this is the top row
        if (position < mNumColumns) {
            if (convertView == null) {
                convertView = new View(mContext);
            }
            // Set empty view with height of ActionBar
            convertView.setLayoutParams(new AbsListView.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT, mActionBarHeight));
            return convertView;
        }

        // Now handle the main ImageView thumbnails
        ImageView imageView;
        if (convertView == null) { // if it's not recycled, instantiate and initialize
            imageView = new RecyclingImageView(mContext);
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageView.setLayoutParams(mImageViewLayoutParams);
        } else { // Otherwise re-use the converted view
            imageView = (ImageView) convertView;
        }

        // Check the height matches our calculated column width
        if (imageView.getLayoutParams().height != mItemHeight) {
            imageView.setLayoutParams(mImageViewLayoutParams);
        }

        // Finally load the image asynchronously into the ImageView, this also takes care of
        // setting a placeholder image while the background thread runs
        Photo photo = DataStore.photosInfoOfTag.photo.get(position - mNumColumns);
        String photoUrl = DataStore.imageUrlPart1 + Integer.toString(photo.getFarm()) +
                          DataStore.imageUrlPart2 + photo.getServer() + "/" + 
                          photo.getId() + "_" + photo.getSecret() +
                          DataStore.imageUrlPart3;
        mImageFetcher.loadImage(photoUrl, imageView);
        //mImageFetcher.loadImage(Images.imageThumbUrls[position - mNumColumns], imageView);
        return imageView;
    }

    public void setItemHeight(int height) {
        if (height == mItemHeight) {
            return;
        }
        mItemHeight = height;
        mImageViewLayoutParams =
                new GridView.LayoutParams(LayoutParams.MATCH_PARENT, mItemHeight);
        mImageFetcher.setImageSize(height);
        notifyDataSetChanged();
    }

    public void setNumColumns(int numColumns) {
        mNumColumns = numColumns;
    }
}

05-06 01:04:39.736:E/AndroidRuntime(16356):致命异常:主要

05-06 01:04:39.736: E/AndroidRuntime(16356):
java.lang.IndexOutOfBoundsException:索引 100 无效,大小为 100

05-06 01:04:39.736: E/AndroidRuntime(16356): 在 java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)

05-06 01:04:39.736: E/AndroidRuntime(16356): 在 java.util.ArrayList.get(ArrayList.java:304)

05-06 01:04:39.736: E/AndroidRuntime(16356): 在 com.example.android.bitmapfun.ui.ImageGridFragment$ImageAdapter.getView(ImageGridFragment.java:292)

05-06 01:04:39.736: E/AndroidRuntime(16356): 在 android.widget.AbsListView.obtainView(AbsListView.java:2143)

05-06 01:04:39.736: E/AndroidRuntime(16356): 在 android.widget.GridView.makeAndAddView(GridView.java:1341)

05-06 01:04:39.736: E/AndroidRuntime(16356): 在 android.widget.GridView.makeRow(GridView.java:341)

05-06 01:04:39.736: E/AndroidRuntime(16356): 在 android.widget.GridView.fillDown(GridView.java:283)

05-06 01:04:39.736: E/AndroidRuntime(16356): 在 android.widget.GridView.fillGap(GridView.java:243)

05-06 01:04:39.736: E/AndroidRuntime(16356): 在 android.widget.AbsListView.trackMotionScroll(AbsListView.java:4930)

05-06 01:04:39.736: E/AndroidRuntime(16356): 在 android.widget.AbsListView$FlingRunnable.run(AbsListView.java:4087)

05-06 01:04:39.736: E/AndroidRuntime(16356): 在 android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)

05-06 01:04:39.736: E/AndroidRuntime(16356): 在 android.view.Choreographer.doCallbacks(Choreographer.java:562)

05-06 01:04:39.736: E/AndroidRuntime(16356): 在 android.view.Choreographer.doFrame(Choreographer.java:531)

05-06 01:04:39.736: E/AndroidRuntime(16356): 在 android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)

05-06 01:04:39.736: E/AndroidRuntime(16356): 在 android.os.Handler.handleCallback(Handler.java:725)

05-06 01:04:39.736: E/AndroidRuntime(16356): 在 android.os.Handler.dispatchMessage(Handler.java:92)

05-06 01:04:39.736: E/AndroidRuntime(16356): 在 android.os.Looper.loop(Looper.java:137)

05-06 01:04:39.736: E/AndroidRuntime(16356): 在 android.app.ActivityThread.main(ActivityThread.java:5041)

05-06 01:04:39.736: E/AndroidRuntime(16356): 在 java.lang.reflect.Method.invokeNative(Native Method)

05-06 01:04:39.736: E/AndroidRuntime(16356): 在 java.lang.reflect.Method.invoke(Method.java:511)

05-06 01:04:39.736: E/AndroidRuntime(16356): 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)

05-06 01:04:39.736: E/AndroidRuntime(16356): 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)

05-06 01:04:39.736: E/AndroidRuntime(16356): 在 dalvik.system.NativeStart.main(Native Method)

【问题讨论】:

  • 这是getView() 方法中的完整代码吗?如果不是,请发布它,否则我看不到您的代码如何设法通过负索引列表检索(因为位置从 0 开始并假设 mNumColumns 不是 0)。
  • @Luksprog,我已经编辑了代码。
  • 您发布的内容不清楚。 Images.imageThumbUrls.length 在您的代码中代表 DataStore.photosInfoOfTag.total?在这种情况下,如果Images.imageThumbUrls.length 是 99,那么异常如何说明您有一个包含 100 个元素的列表?
  • @Luksprog,Images.imageThumbUrls.length是99,我改成DataStore.photosInfoOfTag.total,大约是10000。
  • @Luksprog,非常感谢您的患者。我犯了一个错误。 DataStore.photosInfoOfTag.total 的长度为 100。很抱歉浪费您的时间。

标签: android android-gridview baseadapter


【解决方案1】:

小心,当 getCount() 返回的值大于适配器上的项目数时(通常只填充单元格),您需要检查当前边界是否从未被绕过,如果是则返回空视图(或有一定背景的人)。

您的代码:

public int getCount() {
        //return Images.imageThumbUrls.length + mNumColumns;
        return DataStore.photosInfoOfTag.total + mNumColumns;
}

应该只返回 DataStore.photosInfoOfTag.total

另外,不要使用这种静态的东西,你应该使用 List 来代替适配器的数据。

【讨论】:

  • 我对这个问题感到困惑。返回DataStore.photosInfoOfTag.total + mNumColumns; 的原因是因为“这是相当标准的,除了 GridView 中的列数用于创建假的空视图顶行,因为我们使用透明的 ActionBar 并且不想要真正的顶行图像开始被它覆盖。”
  • @Macros,非常感谢您的患者。我犯了一个错误。 DataStore.photosInfoOfTag.total的长度是100。很抱歉浪费了您的时间。
  • 不,我通常使用大于数据的计数来填充 GridView 中一行的剩余空间,但对于这种情况,您需要返回一个空视图。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-22
  • 1970-01-01
  • 2015-11-05
  • 1970-01-01
相关资源
最近更新 更多