java – GridView scrollBar:动态添加图像时的不稳定行为
我正在尝试制作某种图像库,其中图像在后台加载,并在完成加载后动态添加到gridView.图像加载效果很好,但如果gridView中的图像超出屏幕高度,则gridView的滚动行为将无法按预期工作.
出于测试目的,我正在加载15个虚拟图像,两列中的aligend.加载完所有图像后,根据右侧的scrollBar,gridView的高度似乎符合其内容高度(左侧列中的8个图像或行).但是,如果我尝试滚动到第4行项目以到达视图的底部(第5/6/7/8行),则scrollBar指示gridView的高度已更改并且已到达视图的底部.滚过第4行是不可能的.如果我再次向上滚动,gridView似乎再次包含8行. 左视图:gridView似乎包含15个图像. 我已经尝试过使用不同的方法,如here提到的ExpandableHeightViewGrid,但滚动行为是相同的.我会选择在一行中使用具有多列图像的gridView(比如使用listView),因为如果我要加载超过15个图像,滚动到底部会非常烦人. 这是我的代码:
<?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>
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; } } 如果有人可以帮助我帮助我修复我的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,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,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); } 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,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现在都可以正常工作.我不知道对一个人自己的问题是否是常见做法,但在这样做时我认为它可以帮助那些面临类似问题的人. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |