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