Java GridView滚动条:动态添加图像时的不稳定行为

Java GridView滚动条:动态添加图像时的不稳定行为,java,android,gridview,Java,Android,Gridview,我正在尝试制作某种图像库,其中图像在后台加载,并在加载完成后动态添加到gridView。图像加载工作得很好,但是如果gridView中的图像超过屏幕高度,gridView的滚动行为将无法正常工作 出于测试目的,我加载了15个虚拟图像,在两列中对齐。加载所有图像后,根据右侧的滚动条,gridView的高度似乎与其内容高度相匹配(左列有8个图像或行)。但如果我试图滚动第4行项目以到达视图底部(第5/6/7/8行),滚动条表示gridView的高度已更改,并且已到达视图底部。无法滚动到第四行。如果我再

我正在尝试制作某种图像库,其中图像在后台加载,并在加载完成后动态添加到gridView。图像加载工作得很好,但是如果gridView中的图像超过屏幕高度,gridView的滚动行为将无法正常工作

出于测试目的,我加载了15个虚拟图像,在两列中对齐。加载所有图像后,根据右侧的滚动条,gridView的高度似乎与其内容高度相匹配(左列有8个图像或行)。但如果我试图滚动第4行项目以到达视图底部(第5/6/7/8行),滚动条表示gridView的高度已更改,并且已到达视图底部。无法滚动到第四行。如果我再次向上滚动,gridView似乎又包含8行

左视图:gridView似乎包含15个图像。 右视图:gridView突然似乎只包含8幅图像

我已经尝试过使用不同的方法,比如前面提到的ExpandableHeightViewGrid,但是滚动行为是相同的。我会选择使用一个gridView,它在一行上有多个图像列(就像使用listView),因为如果要加载的图像超过15个,滚动到底部会非常烦人

这是我的密码:

photo_gallery.xml

PhotoGalleryImageAdapter(也简化了)


如果有人能在这里帮助我,并帮助我修复gridView,以便我可以按预期滚动所有加载的图像,我将非常高兴。

好吧,看来我自己解决了这个问题,忽略了它。由于不知道该怎么做,我跳过了修复gridView之后,我使用LruCache(如Android开发者所示)实现了缓存图像以节省一些内存。突然,gridView的滚动行为也被修复了

这是我的零钱:

PhotoGalleryImageAdapter(现在带有缓存)

正如预期的那样,我需要在加载之前设置图像边界

由于我将gridView的
numColumns
参数更改为“自动拟合”,因此图像的宽度/高度(100dp+stretchMode columnWidth)计算如下:

int imagesPerRow = screenSize.x / (int)(100 * mContext.getResources().getDisplayMetrics().density);
imageSize = screenSize.x / imagesPerRow;
在加载imageView的bitmapImage之前,我创建了一个空位图图像并将其分配给imageView(找到代码):


无论是否使用LruCache,gridView现在都按预期工作。我不知道回答自己的问题是否是一种常见的做法,但我认为这样做可以帮助其他面临类似问题的人。

您是否尝试过制作GridView布局\u height=match\u parent?Jep,但这也没有奏效:-/
public class PhotoGalleryActivity extends myBaseView {

    private GridView gridView;
    private PhotoGalleryImageAdapter imageAdapter;
    private PhotoGalleryModel[] photoGalleryModels;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.photo_gallery);
        gridView = (GridView) findViewById(R.id.gridView);

        loadImages();
    }

    void loadImages() {

        photoGalleryModels = PhotoGalleryModel.getFakeData();
        imageAdapter = new PhotoGalleryImageAdapter(this, photoGalleryModels);
        gridView.setAdapter(imageAdapter);
    }
}
public class PhotoGalleryImageAdapter extends BaseAdapter {

    private Context mContext;
    private PhotoGalleryModel[] photoGalleryModels;

    public PhotoGalleryImageAdapter(Context c, PhotoGalleryModel[] models){
        mContext = c;
        photoGalleryModels = models;
    }

    @Override
    public int getCount() { return photoGalleryModels.length; }

    @Override
    public Object getItem(int position) { return null; }

    @Override
    public long getItemId(int position) { return 0; }

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

        final ImageView imageView = new ImageView(mContext);    
        DownloadImageWithURL(photoGalleryModels[position].thumb_image_url, new MyHttpCallback() {
            @Override
            public void MyHttpCallback_OnSuccess(Object data, String responseString)
            {
                if(data instanceof Bitmap) {
                    imageView.setImageBitmap((Bitmap)data);
                }
            }

            @Override
            public void MyHttpCallback_OnError(String responseString, ErrorDataModel error)
            {}
        });

        convertView = imageView;    
        return convertView;
    }
}
public class PhotoGalleryImageAdapter extends BaseAdapter {

    private Context mContext;
    private PhotoGalleryModel[] photoGalleryModels;
    private LruCache<String, Bitmap> mMemoryCache;

    public PhotoGalleryImageAdapter(Context c, PhotoGalleryModel[] models){
        mContext = c;
        photoGalleryModels = models;

        final int maxMemory = (int)(Runtime.getRuntime().maxMemory() / 1024);
        final int cacheSize = maxMemory / 8;

        mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
            @Override
        protected int sizeOf(String key, Bitmap bitmap) {
                return bitmap.getByteCount() / 1024;
            }
        };
    }

    @Override
    public int getCount() { return photoGalleryModels.length; }

    @Override
    public Object getItem(int position) { return null; }

    @Override
    public long getItemId(int position) { return 0; }

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

        final ImageView imageView = new ImageView(mContext);
        final String imageKey = photoGalleryModels[position].thumb_image_url;
        final Bitmap bitmapImage = mMemoryCache.get(imageKey);

        if (bitmapImage != null) {
            imageView.setImageBitmap(bitmapImage);
        }
        else {

            DownloadImageWithURL(photoGalleryModels[position].thumb_image_url, new MyHttpCallback() {
                @Override
                public void MyHttpCallback_OnSuccess(Object data, String responseString) {
                    if (data instanceof Bitmap) {
                        mMemoryCache.put(imageKey, (Bitmap)data);
                        imageView.setImageBitmap((Bitmap)data);
                    }
                }

                @Override
                public void MyHttpCallback_OnError(String responseString, ErrorDataModel error)
                {}
            });
        }

        convertView = imageView;
        return convertView;
    }

}
public View getView(int position, View convertView, ViewGroup parent) {

    final ImageView imageView;
       // set the imagge's bounds if it is not loaded yet
    if (convertView == null) {
        imageView = new ImageView(mContext);
        imageView.setLayoutParams(new ViewGroup.LayoutParams(imageSize, imageSize));
        imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
        imageView.setPadding(0, 0, 0, 0);
    }
    else {
        imageView = (ImageView) convertView;
    }

    final String imageKey = photoGalleryModels[position].thumb_image_url;
    final Bitmap bitmapImage = mMemoryCache.get(imageKey);

    if (bitmapImage != null) {
        imageView.setImageBitmap(bitmapImage);
    }
    else {
        imageView.setImageBitmap(emptyBitmap);
        DownloadImageWithURL(photoGalleryModels[position].thumb_image_url, new MyHttpCallback() {
            @Override
            public void MyHttpCallback_OnSuccess(Object data, String responseString) {
                    if (data instanceof Bitmap) {
                    mMemoryCache.put(imageKey, (Bitmap)data);
                    imageView.setImageBitmap((Bitmap)data);
                }
            }

            @Override
            public void MyHttpCallback_OnError(String responseString, ErrorDataModel error)
            {}
        });
    }
    convertView = imageView;
    return convertView;
}
int imagesPerRow = screenSize.x / (int)(100 * mContext.getResources().getDisplayMetrics().density);
imageSize = screenSize.x / imagesPerRow;
emptyBitmap = Bitmap.createBitmap(imageSize, imageSize, Bitmap.Config.ARGB_8888);