我正在尝试创建一个图库应用,只是为了向用户显示图片。
该应用已经在运行,但网格滚动缓慢且不流畅。
我不知道我还能做些什么才能让表现更好。我已经使用LruCache和Async任务来加载图片。
GridAdapter
package abcde.xyz;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.support.v4.util.LruCache;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import java.util.ArrayList;
/**
* Created by Lucas on 25/03/2017.
*/
public class GridImagesAdapter extends ArrayAdapter {
private Context context;
private int layoutResourceId;
private ArrayList data = new ArrayList();
public static LruCache<Integer, Bitmap> mMemoryCache;
public GridImagesAdapter(Context context, int layoutResourceId, ArrayList<Integer> data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
final int cacheSize = maxMemory / 4;
if(mMemoryCache == null){
mMemoryCache = new LruCache<Integer, Bitmap>(cacheSize) {
@Override
protected int sizeOf(Integer key, Bitmap bitmap) {
return bitmap.getByteCount() / 1024;
}
};
}
mMemoryCache.evictAll();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
ImageView image = (ImageView)row.findViewById(R.id.image);
final Integer item = (Integer)data.get(position);
image.setImageBitmap(null);
ImageGridHandler handler = new ImageGridHandler(context, image);
handler.execute(item);
}
return row;
}
}
ImageGridHandler
package abcde.xyz;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.ImageView;
import java.lang.ref.WeakReference;
/**
* Created by Lucas on 29/03/2017.
*/
public class ImageGridHandler extends AsyncTask<Integer, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
private Context context;
public ImageGridHandler(Context context, ImageView img){
imageViewReference = new WeakReference<ImageView>(img);
this.context = context;
}
@Override
protected Bitmap doInBackground(Integer... params) {
return loadBitmap(params[0]);
}
@Override
protected void onPostExecute(Bitmap result) {
final ImageView imageView = imageViewReference.get();
if(imageView != null) {
//imageView.setScaleType(ImageView.ScaleType.CENTER);
imageView.setImageBitmap(result);
}
}
public void addBitmapToMemoryCache(Integer key, Bitmap bitmap) {
if (getBitmapFromMemCache(key) == null) {
GridImagesAdapter.mMemoryCache.put(key, bitmap);
}
}
public Bitmap getBitmapFromMemCache(Integer key) {
return GridImagesAdapter.mMemoryCache.get(key);
}
public Bitmap loadBitmap(Integer resId) {
Bitmap bitmap = getBitmapFromMemCache(resId);
if (bitmap == null) {
Log.d("ImageGridHandler", "Loading: " + resId);
if(resId != null) {
bitmap = MediaStore.Images.Thumbnails.getThumbnail(
context.getContentResolver(), resId,
MediaStore.Images.Thumbnails.MICRO_KIND,
null);
if(bitmap != null) {
addBitmapToMemoryCache(resId, bitmap);
}
}
Log.d("GRIDADAPTER", "ImageLoaded");
}
return bitmap;
}
}
布局
content_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="umdev.images24.MainActivity"
tools:showIn="@layout/activity_main">
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/swipeRefresh"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
tools:layout_editor_absoluteY="8dp"
tools:layout_editor_absoluteX="8dp">
<GridView
android:id="@+id/gridView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="0dp"
android:drawSelectorOnTop="true"
android:gravity="center"
android:columnWidth="100dp"
android:numColumns="auto_fit"
android:stretchMode="columnWidth"
android:verticalSpacing="0dp"
android:focusable="true"
android:clickable="true"
android:fastScrollEnabled="true"/>
</android.support.v4.widget.SwipeRefreshLayout>
</android.support.constraint.ConstraintLayout>
grid_item_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="2dp"
android:background="#fff">
<ImageView
android:id="@+id/image"
android:layout_width="120dp"
android:layout_height="120dp" />
</LinearLayout>
答案 0 :(得分:0)
它并不快速而顺畅,因为你不是在缓存。我有同样的问题,我使用Universal Image loader,使用此库在网格视图中调整图像大小。
Git-Hub Universal Image Loader
它使用url获取图像,然后将其转换为位图,然后调整大小。因此,如果您只想创建一个简单的图库。然后你可以像你一样获取SD卡图像并将其传递给通用图像加载器的方法 ImageLoader()
例如 -
String path="file://"+String.valueOf(wholeList.get(i));//Your Image path
ImageLoader.getInstance().displayImage(path,holder.image,options,new SimpleImageLoadingListener() {
@Override
public void onLoadingStarted(String imageUri, View view) {
holder.progressBar.setProgress(0);
holder.progressBar.setVisibility(View.VISIBLE);
}
@Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
holder.progressBar.setVisibility(View.GONE);
}
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
holder.progressBar.setVisibility(View.GONE);
}
}, new ImageLoadingProgressListener() {
@Override
public void onProgressUpdate(String imageUri, View view, int current, int total) {
holder.progressBar.setProgress(Math.round(100.0f * current / total));
}});
return convertView;
}
private static class ViewHolder {
ImageView image;
ProgressBar progressBar;
}
**注意:这不是完整的代码,它只是它的一部分,我建议你先检查一下Git hub链接** - GitHub Universal Image Loader
答案 1 :(得分:0)
您可以使用Glide,Picassa或ImageLoader加载图像并避免使用 由于在图像中加载图像所花费的时间而发生的滚动问题 图
例如在Glide中
Glide.with(getActivity()).load(Uri.fromFile(new File(String.valueOf(getItem(position))))).into(ivPhoto);
答案 2 :(得分:0)
在加载图像之前,我们必须调整它以避免ImageView缩放。
将缩小版本加载到内存中
https://developer.android.com/topic/performance/graphics/load-bitmap.html
谢谢@GT