如何在加载图像时在片段之间切换时避免 jerk/lag/struck
How to avoid jerk/lag/struck while switching between fragments while loading images
这是我用来将图像文件夹从设备存储卡加载到我的应用程序中的代码。
在此代码中,我使用 file 对象获取图像路径,并将该对象传递到我设置的 adapter图片。
File file= new File(Environment.getExternalStorageDirectory()
+ File.separator + "Pictures" + File.separator + "test");
final File[] files = file.listFiles();
for (File _file : files) {
myAdapter.add(_file.getAbsolutePath());
}
但是我在打开这个特定片段时发现有混蛋。因为 一次加载所有图像 并显示它们需要时间,并且在滚动页面时发现相同的 混蛋 。
这是我的 适配器 class 看起来像,
public class ImageAdapter extends BaseAdapter{
public Context mContext;
ArrayList<String> itemList = new ArrayList<>();
public ImageAdapter(Context c) {
mContext = c;
}
public void add(String path) {
itemList.add(path);
}
@Override
public int getCount() {
return itemList.size();
}
@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(180dp,180dp);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(EIGHT, EIGHT, EIGHT, EIGHT);
} else {
imageView = (ImageView) convertView;
}
Bitmap bm = decodeSampledBitmapFromUri(itemList.get(position), 180dp,180dp);
imageView.setImageBitmap(bm);
return imageView;
}
public Bitmap decodeSampledBitmapFromUri(String path, int reqWidth, int reqHeight) {
Bitmap bm = null;
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
options.inJustDecodeBounds = false;
bm = BitmapFactory.decodeFile(path, options);
return bm;
}
public int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
if (width > height) {
inSampleSize = Math.round((float) height / (float) reqHeight);
} else {
inSampleSize = Math.round((float) width / (float) reqWidth);
}
}
return inSampleSize;
}
自己解码位图非常好,但你不应该在 UI 线程中进行,使用像 Picasso 或 Glide 这样的库,或者如果你真的想自己进行解码,请在另一个线程中进行,解码位图是昂贵的并且导致滞后
使用 Picasso 或后台线程加载图像。
此外,使用 Picasso,您可以在加载图像时设置占位符、错误图像时的替代图像、适合图像等。结果将非常专业。
ImageView imageView = (ImageView) FindViewById(...);
Picasso.with(getActivity())
.load(new File("path-to-file/file.png"))
.placeholder(R.drawable.user_placeholder)
.error(R.drawable.user_placeholder_error)
.fit()
.into(imageView);
这是我用来将图像文件夹从设备存储卡加载到我的应用程序中的代码。
在此代码中,我使用 file 对象获取图像路径,并将该对象传递到我设置的 adapter图片。
File file= new File(Environment.getExternalStorageDirectory()
+ File.separator + "Pictures" + File.separator + "test");
final File[] files = file.listFiles();
for (File _file : files) {
myAdapter.add(_file.getAbsolutePath());
}
但是我在打开这个特定片段时发现有混蛋。因为 一次加载所有图像 并显示它们需要时间,并且在滚动页面时发现相同的 混蛋 。
这是我的 适配器 class 看起来像,
public class ImageAdapter extends BaseAdapter{
public Context mContext;
ArrayList<String> itemList = new ArrayList<>();
public ImageAdapter(Context c) {
mContext = c;
}
public void add(String path) {
itemList.add(path);
}
@Override
public int getCount() {
return itemList.size();
}
@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(180dp,180dp);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(EIGHT, EIGHT, EIGHT, EIGHT);
} else {
imageView = (ImageView) convertView;
}
Bitmap bm = decodeSampledBitmapFromUri(itemList.get(position), 180dp,180dp);
imageView.setImageBitmap(bm);
return imageView;
}
public Bitmap decodeSampledBitmapFromUri(String path, int reqWidth, int reqHeight) {
Bitmap bm = null;
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
options.inJustDecodeBounds = false;
bm = BitmapFactory.decodeFile(path, options);
return bm;
}
public int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
if (width > height) {
inSampleSize = Math.round((float) height / (float) reqHeight);
} else {
inSampleSize = Math.round((float) width / (float) reqWidth);
}
}
return inSampleSize;
}
自己解码位图非常好,但你不应该在 UI 线程中进行,使用像 Picasso 或 Glide 这样的库,或者如果你真的想自己进行解码,请在另一个线程中进行,解码位图是昂贵的并且导致滞后
使用 Picasso 或后台线程加载图像。 此外,使用 Picasso,您可以在加载图像时设置占位符、错误图像时的替代图像、适合图像等。结果将非常专业。
ImageView imageView = (ImageView) FindViewById(...);
Picasso.with(getActivity())
.load(new File("path-to-file/file.png"))
.placeholder(R.drawable.user_placeholder)
.error(R.drawable.user_placeholder_error)
.fit()
.into(imageView);