gpt4 book ai didi

java - GridView 滚动条 : erratic behaviour when dynamically adding images

转载 作者:太空宇宙 更新时间:2023-11-03 11:04:22 25 4
gpt4 key购买 nike

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

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

same gridView with different content size

左 View :gridView 似乎包含 15 张图像。右 View :gridView突然好像只有8张图片

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

这是我的代码:

photo_gallery.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

<!-- This is basically a HorizontalScrollView where i add some buttons -->
<com.my.HorizontalButtonScrollList
android:id="@+id/horizontalButtonScrollList"
android:layout_width="match_parent"
android:layout_height="50dip">
</com.my.HorizontalButtonScrollList>

<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">

<GridView
android:id="@+id/gridView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnWidth="100dp"
android:numColumns="2"
android:verticalSpacing="0dp"
android:horizontalSpacing="0dp"
android:stretchMode="columnWidth"
android:gravity="center"
android:scrollbars="vertical">
</GridView>

</android.support.v4.widget.SwipeRefreshLayout>

</LinearLayout>

PhotoGalleryActivity.java (I simplified the code for better readability)

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);
}
}

PhotoGalleryImageAdapter (also simplified)

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;
}
}

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

最佳答案

嗯,看来是我自己忽略了,解决了这个问题。在我跳过修复 gridView 因为我不知道该怎么做之后,我实现了使用 LruCache 缓存图像(如 Android 开发人员的 training page 所示)以节省一些内存。突然之间,gridView 的滚动行为也得到了修复。

这是我的改动:

PhotoGalleryImageAdapter(现在有缓存)

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;
}

}

我很高兴 gridView 终于可以工作了,但我不高兴的是它在没有缓存图像的情况下对我不起作用。我可能应该在加载图像之前在 imageAdapter 的 getView() 方法中设置 imageView 的边界。我将尝试在不使用缓存的情况下修复 gridView,如果我找到了解决方案,我会更新我的答案,以防有人遇到同样的问题。在那之前,我很高兴我设法让它发挥作用:)

更新:

我终于让它在有缓存和没有缓存的情况下都能工作。这是我更新的 PhotoGalleryImageAdapter:

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;
}

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

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

int imagesPerRow = screenSize.x / (int)(100 * mContext.getResources().getDisplayMetrics().density);
imageSize = screenSize.x / imagesPerRow;

在加载 imageView 的 bitmapImage 之前,我创建了一个空位图图像并将其分配给 imageView(找到代码 here ):

emptyBitmap = Bitmap.createBitmap(imageSize, imageSize, Bitmap.Config.ARGB_8888);

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

关于java - GridView 滚动条 : erratic behaviour when dynamically adding images,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35462364/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com