带滑行的回收器视图
Recycler view with glide
我在使用给定代码时遇到以下问题:
- 当我向后滚动 recyclerview 时图像会重新加载
- 加载了错误的缩略图(当我来回滚动时它们不断变化)
- UI 挂起(我尝试线程但问题仍然存在)
视频文件不存在这些问题(外部if的else部分)
内部视频适配器:
if(videoFiles.get(position).getType().equals(MediaStore.Files.FileColumns.MEDIA_TYPE_AUDIO+"")){
if(coverpicture(videoFiles.get(position).getPath())!=null) {
Glide.with(mContext)
.load(coverpicture(videoFiles.get(position).getPath()))
.diskCacheStrategy(DiskCacheStrategy.ALL)
.placeholder(circularProgressDrawable)
.into(holder.thumbnail);
}
else {
Glide.with(mContext)
.load(new File(videoFiles.get(position).getPath()))
.placeholder(R.drawable.ic_baseline_music_note)
.into(holder.thumbnail);
}
} else {
Glide.with(mContext)
.load(new File(videoFiles.get(position).getPath()))
.placeholder(circularProgressDrawable)
.into(holder.thumbnail);
}
我是这样称呼视频适配器的:
videoAdapter = new VideoAdapter(getActivity(),videoFiles);
函数封面图:
private Bitmap coverpicture(String path) {
final MediaMetadataRetriever[] mr = new MediaMetadataRetriever[1];
final byte[][] byte1 = new byte[1][1];
Thread ttt = new Thread(){
@Override
public void run() {
super.run();
mr[0] = new MediaMetadataRetriever();
mr[0].setDataSource(path);
byte1[0] = mr[0].getEmbeddedPicture();
mr[0].release();
}
};
ttt.start();
while(true){
if(!ttt.isAlive()){
if(byte1[0] != null) {
return BitmapFactory.decodeByteArray(byte1[0], 0, byte1[0].length);
}
else {
return null;
}
}
}
}
编辑:
当我用
替换第一个滑行语句时,错误的缩略图问题得到解决
(如果有人解释原因会很有用)
Glide.with(mContext)
.load(coverpicture(videoFiles.get(position).getPath()))
.diskCacheStrategy(DiskCacheStrategy.ALL)
.placeholder(circularProgressDrawable)
.into(new DrawableImageViewTarget(holder.thumbnail));
- 在 recyclerview 适配器的 onBindViewHolder 中,在后台线程中,加载滑行图像 first.Then 使用 view.post[=27 显示它=]
new Thread(()->{
Bitmap b =coverpicture(videoFiles.get(position).getPath());
Glide.with(mContext).downloadOnly().load(b);
holder.thumbnail.post(() -> {
Glide.with(mContext).clear(holder.thumbnail);
Glide.with(holder.thumbnail.getContext())
.load(new File(videoFiles.get(position).getPath()))
.placeholder(circularProgressDrawable)
.format(DecodeFormat.PREFER_RGB_565)
.into(new DrawableImageViewTarget(holder.thumbnail));
}
}).start();
2。 post
中已经提到
3。将 coverpicture() 更改为
static Bitmap coverpicture(String path) {
MediaMetadataRetriever mr;
byte[] byte1 = new byte[1];
mr = new MediaMetadataRetriever();
mr.setDataSource(path);
try {
byte1 = mr.getEmbeddedPicture();
mr.release();
}catch (Exception e){
e.printStackTrace();
}
if(byte1 != null) {
return BitmapFactory.decodeByteArray(byte1, 0, byte1.length);
}
else {
return null;
}
}
不需要在 coverpicture() 中线程化,因为它是从后台线程调用的
此外,recyclerview 中的以下优化将有所帮助
recyclerView.setHasFixedSize(true);
recyclerView.setItemViewCacheSize(20);
recyclerView.setDrawingCacheEnabled(true);
recyclerView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
我在使用给定代码时遇到以下问题:
- 当我向后滚动 recyclerview 时图像会重新加载
- 加载了错误的缩略图(当我来回滚动时它们不断变化)
- UI 挂起(我尝试线程但问题仍然存在)
视频文件不存在这些问题(外部if的else部分)
内部视频适配器:
if(videoFiles.get(position).getType().equals(MediaStore.Files.FileColumns.MEDIA_TYPE_AUDIO+"")){
if(coverpicture(videoFiles.get(position).getPath())!=null) {
Glide.with(mContext)
.load(coverpicture(videoFiles.get(position).getPath()))
.diskCacheStrategy(DiskCacheStrategy.ALL)
.placeholder(circularProgressDrawable)
.into(holder.thumbnail);
}
else {
Glide.with(mContext)
.load(new File(videoFiles.get(position).getPath()))
.placeholder(R.drawable.ic_baseline_music_note)
.into(holder.thumbnail);
}
} else {
Glide.with(mContext)
.load(new File(videoFiles.get(position).getPath()))
.placeholder(circularProgressDrawable)
.into(holder.thumbnail);
}
我是这样称呼视频适配器的:
videoAdapter = new VideoAdapter(getActivity(),videoFiles);
函数封面图:
private Bitmap coverpicture(String path) {
final MediaMetadataRetriever[] mr = new MediaMetadataRetriever[1];
final byte[][] byte1 = new byte[1][1];
Thread ttt = new Thread(){
@Override
public void run() {
super.run();
mr[0] = new MediaMetadataRetriever();
mr[0].setDataSource(path);
byte1[0] = mr[0].getEmbeddedPicture();
mr[0].release();
}
};
ttt.start();
while(true){
if(!ttt.isAlive()){
if(byte1[0] != null) {
return BitmapFactory.decodeByteArray(byte1[0], 0, byte1[0].length);
}
else {
return null;
}
}
}
}
编辑: 当我用
替换第一个滑行语句时,错误的缩略图问题得到解决(如果有人解释原因会很有用)
Glide.with(mContext)
.load(coverpicture(videoFiles.get(position).getPath()))
.diskCacheStrategy(DiskCacheStrategy.ALL)
.placeholder(circularProgressDrawable)
.into(new DrawableImageViewTarget(holder.thumbnail));
- 在 recyclerview 适配器的 onBindViewHolder 中,在后台线程中,加载滑行图像 first.Then 使用 view.post[=27 显示它=]
new Thread(()->{
Bitmap b =coverpicture(videoFiles.get(position).getPath());
Glide.with(mContext).downloadOnly().load(b);
holder.thumbnail.post(() -> {
Glide.with(mContext).clear(holder.thumbnail);
Glide.with(holder.thumbnail.getContext())
.load(new File(videoFiles.get(position).getPath()))
.placeholder(circularProgressDrawable)
.format(DecodeFormat.PREFER_RGB_565)
.into(new DrawableImageViewTarget(holder.thumbnail));
}
}).start();
2。 post
中已经提到3。将 coverpicture() 更改为
static Bitmap coverpicture(String path) {
MediaMetadataRetriever mr;
byte[] byte1 = new byte[1];
mr = new MediaMetadataRetriever();
mr.setDataSource(path);
try {
byte1 = mr.getEmbeddedPicture();
mr.release();
}catch (Exception e){
e.printStackTrace();
}
if(byte1 != null) {
return BitmapFactory.decodeByteArray(byte1, 0, byte1.length);
}
else {
return null;
}
}
不需要在 coverpicture() 中线程化,因为它是从后台线程调用的
此外,recyclerview 中的以下优化将有所帮助
recyclerView.setHasFixedSize(true);
recyclerView.setItemViewCacheSize(20);
recyclerView.setDrawingCacheEnabled(true);
recyclerView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);