Skip to content
Snippets Groups Projects
Commit 33d5ce9a authored by Geoffrey Métais's avatar Geoffrey Métais
Browse files

Factorize code in image loader

parent 66594e27
No related branches found
No related tags found
No related merge requests found
......@@ -36,7 +36,6 @@
android:layout_height="@dimen/audio_browser_item_size"
android:layout_gravity="center"
vlc:media="@{item}"
vlc:binding="@{holder.vdb}"
android:background="@{cover}" />
<LinearLayout
......
......@@ -23,7 +23,7 @@
name="protocol"
type="String"/>
<variable
name="image"
name="cover"
type="android.graphics.drawable.BitmapDrawable"/>
</data>
<LinearLayout
......@@ -62,7 +62,7 @@
android:text="@{protocol}"
android:textSize="11sp"
android:textColor="@color/whitetransparent"
android:background="@{image}"
android:background="@{cover}"
vlc:mediaWithArt="@{item}" />
<LinearLayout
......
......@@ -34,7 +34,6 @@
android:scaleType="fitCenter"
android:layout_alignParentLeft="true"
vlc:media="@{item}"
vlc:binding="@{holder.getDataBinding()}"
android:src="@{cover}"/>
<LinearLayout
android:layout_width="match_parent"
......
......@@ -62,7 +62,6 @@
android:background="@{cover}"
android:scaleType="fitXY"
android:src="@drawable/black_gradient"
vlc:binding="@{holder.binding}"
vlc:media="@{media}" />
<LinearLayout
......
......@@ -59,7 +59,6 @@
android:layout_width="120dp"
android:layout_height="75dp"
vlc:media="@{media}"
vlc:binding="@{holder.binding}"
android:scaleType="fitXY"
android:background="@{cover}" />
......
package org.videolan.vlc.gui;
import android.content.Context;
import android.databinding.ViewDataBinding;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.ViewGroup;
......@@ -31,7 +30,7 @@ public class SearchResultAdapter extends RecyclerView.Adapter<SearchResultAdapte
notifyDataSetChanged();
}
public void setClickHandler(SearchActivity.ClickHandler clickHandler) {
void setClickHandler(SearchActivity.ClickHandler clickHandler) {
mClickHandler = clickHandler;
}
......@@ -50,9 +49,5 @@ public class SearchResultAdapter extends RecyclerView.Adapter<SearchResultAdapte
binding.setHolder(this);
binding.setHandler(mClickHandler);
}
public ViewDataBinding getDataBinding() {
return binding;
}
}
}
......@@ -115,7 +115,7 @@ public class BaseBrowserAdapter extends RecyclerView.Adapter<BaseBrowserAdapter.
vh.binding.setHasContextMenu(true);
if (fragment instanceof NetworkBrowserFragment && fragment.isRootDirectory())
vh.binding.setProtocol(getProtocol(media));
vh.binding.setImage(getIcon(media));
vh.binding.setCover(getIcon(media));
vh.setContextMenuListener();
vh.setViewBackground(vh.itemView.hasFocus(), mSelectedItems.contains(position));
}
......@@ -153,8 +153,6 @@ public class BaseBrowserAdapter extends RecyclerView.Adapter<BaseBrowserAdapter.
super(v);
binding = DataBindingUtil.bind(v);
binding.setHolder(this);
v.findViewById(R.id.layout_item).setTag(R.id.layout_item, this);
v.setTag(binding);
v.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
......
......@@ -49,7 +49,7 @@ public class FilePickerAdapter extends BaseBrowserAdapter {
vh.binding.setItem(media);
vh.binding.setHasContextMenu(false);
vh.binding.setProtocol(null);
vh.binding.setImage(getIcon(media));
vh.binding.setCover(getIcon(media));
}
//TODO update with different filter types in other cases than subtitles selection
......
......@@ -24,6 +24,7 @@
package org.videolan.vlc.gui.helpers;
import android.databinding.BindingAdapter;
import android.databinding.DataBindingUtil;
import android.databinding.OnRebindCallback;
import android.databinding.ViewDataBinding;
import android.graphics.Bitmap;
......@@ -59,76 +60,13 @@ public class AsyncImageLoader {
public static final BitmapDrawable DEFAULT_COVER_VIDEO_DRAWABLE = new BitmapDrawable(VLCApplication.getAppResources(), DEFAULT_COVER_VIDEO);
public static final Bitmap DEFAULT_COVER_AUDIO = BitmapCache.getFromResource(VLCApplication.getAppResources(), R.drawable.icon);
public static final BitmapDrawable DEFAULT_COVER_AUDIO_DRAWABLE = new BitmapDrawable(VLCApplication.getAppResources(), DEFAULT_COVER_AUDIO);
public static void LoadImage(final Callbacks cbs, final View target){
VLCApplication.runBackground(new Runnable() {
@Override
public void run() {
final Bitmap bitmap = cbs.getImage();
cbs.updateImage(bitmap, target);
}
});
}
public abstract static class CoverFetcher implements AsyncImageLoader.Callbacks {
protected ViewDataBinding binding = null;
private boolean bindChanged = false;
final OnRebindCallback<ViewDataBinding> rebindCallbacks = new OnRebindCallback<ViewDataBinding>() {
@Override
public boolean onPreBind(ViewDataBinding binding) {
bindChanged = true;
return super.onPreBind(binding);
}
@Override
public void onCanceled(ViewDataBinding binding) {
super.onCanceled(binding);
}
@Override
public void onBound(ViewDataBinding binding) {
super.onBound(binding);
}
};
protected CoverFetcher(ViewDataBinding binding){
if (binding != null) {
this.binding = binding;
this.binding.executePendingBindings();
this.binding.addOnRebindCallback(rebindCallbacks);
}
}
public void updateBindImage(final Bitmap bitmap) {}
public void updateImageView(final Bitmap bitmap, View target) {}
@Override
public void updateImage(final Bitmap bitmap, final View target) {
if (binding != null) {
this.binding.removeOnRebindCallback(rebindCallbacks);
if (!bindChanged)
sHandler.post(new Runnable() {
@Override
public void run() {
updateBindImage(bitmap);
}
});
} else {
sHandler.post(new Runnable() {
@Override
public void run() {
updateImageView(bitmap, target);
}
});
}
}
}
/*
* Custom bindings to trigger image (dwon)loading
* Custom bindings to trigger image (down)loading
*/
@BindingAdapter({"imageUri", "binding"})
public static void downloadIcon(final View v, final Uri imageUri, final ViewDataBinding vdb) {
@BindingAdapter({"imageUri"})
public static void downloadIcon(final View v, final Uri imageUri) {
AsyncImageLoader.LoadImage(new Callbacks() {
@Override
public Bitmap getImage() {
......@@ -138,26 +76,22 @@ public class AsyncImageLoader {
@Override
public void updateImage(Bitmap bitmap, View target) {
if (v instanceof ImageView)
setCover((ImageView) v, 0, bitmap, vdb);
updateTargetImage(bitmap, v, 0);
}
}, v);
}
@BindingAdapter({"mediaWithArt"})
public static void downloadIcon(View v, MediaLibraryItem item) {
if (item == null || item.getItemType() != MediaLibraryItem.TYPE_MEDIA)
if (item == null || item.getItemType() != MediaLibraryItem.TYPE_MEDIA ||
TextUtils.isEmpty(item.getArtworkMrl()) || !item.getArtworkMrl().startsWith("http"))
return;
MediaWrapper mw = (MediaWrapper) item;
ViewDataBinding vdb = (ViewDataBinding) v.getTag();
if (TextUtils.isEmpty(mw.getArtworkURL()) || !mw.getArtworkURL().startsWith("http"))
return;
if (vdb == null && v.getTag() instanceof ViewDataBinding)
vdb = (ViewDataBinding) v.getTag();
AsyncImageLoader.LoadImage(new MediaCoverFetcher(vdb, mw), v);
AsyncImageLoader.LoadImage(new MLItemCoverFetcher(v, mw), v);
}
@BindingAdapter({"media", "binding"})
public static void loadPicture(ImageView v, MediaLibraryItem item, ViewDataBinding vdb) {
@BindingAdapter({"media"})
public static void loadPicture(ImageView v, MediaLibraryItem item) {
if (item == null)
return;
if (item instanceof MediaWrapper) {
......@@ -167,143 +101,133 @@ public class AsyncImageLoader {
final Bitmap bitmap = type == MediaWrapper.TYPE_VIDEO ?
BitmapUtil.getPictureFromCache((MediaWrapper) item) : null;
if (bitmap != null) {
setCover(v, type, bitmap, vdb);
updateTargetImage(bitmap, v, type);
return;
}
}
AsyncImageLoader.LoadImage(new MLItemCoverFetcher(v, vdb, item), v);
AsyncImageLoader.LoadImage(new MLItemCoverFetcher(v, item), v);
}
@BindingAdapter({"media"})
public static void loadPicture(ImageView v, MediaWrapper mw) {
ViewDataBinding vdb = null;
if (v.getTag() instanceof ViewDataBinding)
vdb = (ViewDataBinding) v.getTag();
loadPicture(v, mw, vdb);
}
// @BindingAdapter({"item"})
// public static void loadPicture(final ImageView v, final AudioBrowserListAdapter.ListItem item) {
// final Object tag = v.getTag(R.id.media_cover);
// if (tag == null || !(tag instanceof ViewDataBinding))
// return;
// Bitmap bitmap = AudioUtil.getCoverFromMemCache(VLCApplication.getAppContext(), item.mMediaList, 64);
// if (bitmap != null) {
// ((ViewDataBinding) tag).setVariable(BR.cover, new BitmapDrawable(VLCApplication.getAppResources(), bitmap));
// return;
// }
// AsyncImageLoader.LoadImage(new Callbacks() {
// @Override
// public Bitmap getImage() {
// return AudioUtil.getCover(VLCApplication.getAppContext(), item.mMediaList, 64);
// }
//
// @Override
// public void updateImage(final Bitmap bitmap, View target) {
// sHandler.post(new Runnable() {
// @Override
// public void run() {
// setCover(v, MediaWrapper.TYPE_AUDIO, bitmap, (ViewDataBinding) tag);
// }
// });
// }
// }, v);
// }
// @BindingAdapter({"media", "binding"})
// public static void loadPicture(ImageView v, MediaWrapper mw, ViewDataBinding vdb) {
// if (mw instanceof MediaGroup)
// mw = ((MediaGroup) mw).getFirstMedia();
// final Bitmap bitmap = mw.getType() == MediaWrapper.TYPE_VIDEO ?
// BitmapUtil.getPictureFromCache(mw) :
// AudioUtil.getCoverFromMemCache(v.getContext(), mw, 64);
// if (bitmap != null)
// setCover(v, mw.getType(), bitmap, vdb);
// else
// AsyncImageLoader.LoadImage(new MediaCoverFetcher(vdb, mw), v);
//
// }
private static void setCover(ImageView iv, int type, Bitmap bitmap, ViewDataBinding vdb) {
if (vdb != null) {
if (bitmap != null && bitmap.getWidth() != 1 && bitmap.getHeight() != 1) {
vdb.setVariable(BR.scaleType, ImageView.ScaleType.FIT_CENTER);
vdb.setVariable(BR.cover, new BitmapDrawable(VLCApplication.getAppResources(), bitmap));
} else
vdb.setVariable(BR.cover, type == MediaWrapper.TYPE_VIDEO ? DEFAULT_COVER_VIDEO_DRAWABLE : AudioUtil.DEFAULT_COVER);
} else {
iv.setVisibility(View.VISIBLE);
if (bitmap != null && bitmap.getWidth() != 1 && bitmap.getHeight() != 1) {
iv.setScaleType(ImageView.ScaleType.FIT_CENTER);
iv.setImageBitmap(bitmap);
} else {
iv.setImageResource(type == MediaWrapper.TYPE_VIDEO ? R.drawable.ic_no_thumbnail_1610 : R.drawable.icon);
public static void LoadImage(final Callbacks cbs, final View target){
VLCApplication.runBackground(new Runnable() {
@Override
public void run() {
final Bitmap bitmap = cbs.getImage();
cbs.updateImage(bitmap, target);
}
}
});
}
private static class MLItemCoverFetcher extends AsyncImageLoader.CoverFetcher {
MediaLibraryItem item;
int width;
MLItemCoverFetcher(View v, ViewDataBinding binding, MediaLibraryItem item) {
super(binding);
MLItemCoverFetcher(View v, MediaLibraryItem item) {
super(DataBindingUtil.findBinding(v));
this.item = item;
width = v.getWidth();
}
@Override
public Bitmap getImage() {
if (bindChanged)
return null;
String artworkUrl = item.getArtworkMrl();
if (!TextUtils.isEmpty(artworkUrl) && artworkUrl.startsWith("http"))
return HttpImageLoader.downloadBitmap(artworkUrl);
return AudioUtil.readCoverBitmap(Strings.removeFileProtocole(Uri.decode(item.getArtworkMrl())), width);
}
@Override
public void updateImage(Bitmap bitmap, View target) {
updateTargetImage(bitmap, target, binding, item.getItemType() == MediaLibraryItem.TYPE_MEDIA ? ((MediaWrapper) item).getType() : MediaWrapper.TYPE_AUDIO);
if (!bindChanged)
updateTargetImage(bitmap, target, item.getItemType() == MediaLibraryItem.TYPE_MEDIA ? ((MediaWrapper) item).getType() : MediaWrapper.TYPE_AUDIO);
}
}
private static class MediaCoverFetcher extends AsyncImageLoader.CoverFetcher {
final MediaWrapper media;
MediaCoverFetcher(ViewDataBinding binding, MediaWrapper media) {
super(binding);
this.media = media;
private static void updateTargetImage(final Bitmap bitmap, final View target, final int type) {
ViewDataBinding vdb = DataBindingUtil.findBinding(target);
if (vdb != null) {
if (bitmap != null && bitmap.getWidth() != 1 && bitmap.getHeight() != 1) {
vdb.setVariable(BR.scaleType, ImageView.ScaleType.FIT_CENTER);
vdb.setVariable(BR.cover, new BitmapDrawable(VLCApplication.getAppResources(), bitmap));
} else
vdb.setVariable(BR.cover, type == MediaWrapper.TYPE_VIDEO ? DEFAULT_COVER_VIDEO_DRAWABLE : AudioUtil.DEFAULT_COVER);
} else {
final boolean isBitmapValid = bitmap != null && bitmap.getWidth() != 1 && bitmap.getHeight() != 1;
sHandler.post(new Runnable() {
@Override
public void run() {
if (target instanceof ImageView) {
ImageView iv = (ImageView) target;
iv.setVisibility(View.VISIBLE);
if (isBitmapValid) {
iv.setScaleType(ImageView.ScaleType.FIT_CENTER);
iv.setImageBitmap(bitmap);
} else
iv.setImageResource(type == MediaWrapper.TYPE_VIDEO ? R.drawable.ic_no_thumbnail_1610 : R.drawable.icon);
} else if (target instanceof TextView) {
if (isBitmapValid) {
target.setBackgroundDrawable(new BitmapDrawable(VLCApplication.getAppResources(), bitmap));
((TextView) target).setText(null);
}
}
}
});
}
}
@Override
public Bitmap getImage() {
if (!TextUtils.isEmpty(media.getArtworkURL()) && media.getArtworkURL().startsWith("http"))
return HttpImageLoader.downloadBitmap(media.getArtworkURL());
return media.getType() == MediaWrapper.TYPE_VIDEO ? BitmapUtil.fetchPicture(media) :
AudioUtil.getCover(VLCApplication.getAppContext(), media, 64);
abstract static class CoverFetcher implements AsyncImageLoader.Callbacks {
protected ViewDataBinding binding = null;
protected boolean bindChanged = false;
final OnRebindCallback<ViewDataBinding> rebindCallbacks = new OnRebindCallback<ViewDataBinding>() {
@Override
public boolean onPreBind(ViewDataBinding binding) {
bindChanged = true;
return super.onPreBind(binding);
}
@Override
public void onCanceled(ViewDataBinding binding) {
super.onCanceled(binding);
}
@Override
public void onBound(ViewDataBinding binding) {
super.onBound(binding);
}
};
CoverFetcher(ViewDataBinding binding){
if (binding != null) {
this.binding = binding;
this.binding.executePendingBindings();
this.binding.addOnRebindCallback(rebindCallbacks);
}
}
void updateBindImage(final Bitmap bitmap) {}
void updateImageView(final Bitmap bitmap, View target) {}
@Override
public void updateImage(final Bitmap bitmap, final View target) {
updateTargetImage(bitmap, target, binding, media.getType());
}
}
public static void updateTargetImage(final Bitmap bitmap, final View target, final ViewDataBinding binding, final int type) {
sHandler.post(new Runnable() {
@Override
public void run() {
if (target instanceof ImageView)
setCover((ImageView) target, type, bitmap, binding);
else if (target instanceof TextView) {
if (bitmap != null && (bitmap.getWidth() != 1 && bitmap.getHeight() != 1)) {
if (binding != null) {
binding.setVariable(BR.scaleType, ImageView.ScaleType.FIT_CENTER);
binding.setVariable(BR.image, new BitmapDrawable(VLCApplication.getAppResources(), bitmap));
binding.setVariable(BR.protocol, null);
} else {
target.setBackgroundDrawable(new BitmapDrawable(VLCApplication.getAppResources(), bitmap));
((TextView) target).setText(null);
if (binding != null) {
this.binding.removeOnRebindCallback(rebindCallbacks);
if (!bindChanged)
sHandler.post(new Runnable() {
@Override
public void run() {
updateBindImage(bitmap);
}
});
} else {
sHandler.post(new Runnable() {
@Override
public void run() {
updateImageView(bitmap, target);
}
}
});
}
});
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment