Facebook Fresco using wrap_content

I have a bunch of drawings that I want to download with a mural, I want to use the wrap_content size for these images, how can I do this in xml with a mural? Or if xml is not possible, how do you do it in code?

 <com.facebook.drawee.view.SimpleDraweeView android:id="@+id/myImage" android:layout_width="wrap_content" android:layout_height="wrap_content" fresco:placeholderImage="@mipmap/myImage"/> 

The code above does not work unless I set a fixed size.

+13
source share
4 answers

I'm part of the Fresco team, and I was the one who made the design decision not to support wrap-content. The rationale is explained in the documentation. But, in short, the problem is that you cannot guarantee that the image will be available immediately (you may have to get it first), which means that the image size must change after the image arrives. This is in most cases undesirable, and you should probably revise your interface.

In any case, if you really need / need to do this, you can do it as follows:

 void updateViewSize(@Nullable ImageInfo imageInfo) { if (imageInfo != null) { draweeView.getLayoutParams().width = imageInfo.getWidth(); draweeView.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT; draweeView.setAspectRatio((float) imageInfo.getWidth() / imageInfo.getHeight()); } } ControllerListener listener = new BaseControllerListener { @Override public void onIntermediateImageSet(String id, @Nullable ImageInfo imageInfo) { updateViewSize(imageInfo); } @Override public void onFinalImageSet(String id, @Nullable ImageInfo imageInfo, @Nullable Animatable animatable) { updateViewSize(imageInfo); } }; DraweeController controller = draweeControllerBuilder .setUri(uri) .setControllerListener(listener) .build(); draweeView.setController(controller); 

I wrote this code from the top of my head, I have not tested it. But the idea should be clear, and it should work with minor adjustments.

+33
source

Based on @plamenko's answer, I made an individual presentation as follows:

 /** * Works when either height or width is set to wrap_content * The view is resized based on the image fetched */ public class WrapContentDraweeView extends SimpleDraweeView { // we set a listener and update the view aspect ratio depending on the loaded image private final ControllerListener listener = new BaseControllerListener<ImageInfo>() { @Override public void onIntermediateImageSet(String id, @Nullable ImageInfo imageInfo) { updateViewSize(imageInfo); } @Override public void onFinalImageSet(String id, @Nullable ImageInfo imageInfo, @Nullable Animatable animatable) { updateViewSize(imageInfo); } }; public WrapContentDraweeView(Context context, GenericDraweeHierarchy hierarchy) { super(context, hierarchy); } public WrapContentDraweeView(Context context) { super(context); } public WrapContentDraweeView(Context context, AttributeSet attrs) { super(context, attrs); } public WrapContentDraweeView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public WrapContentDraweeView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } @Override public void setImageURI(Uri uri, Object callerContext) { DraweeController controller = ((PipelineDraweeControllerBuilder)getControllerBuilder()) .setControllerListener(listener) .setCallerContext(callerContext) .setUri(uri) .setOldController(getController()) .build(); setController(controller); } void updateViewSize(@Nullable ImageInfo imageInfo) { if (imageInfo != null) { setAspectRatio((float) imageInfo.getWidth() / imageInfo.getHeight()); } } } 

You can include this class in XML , an example usage:

 <com.example.ui.views.WrapContentDraweeView android:id="@+id/simple_drawee_view" android:layout_width="match_parent" android:layout_height="wrap_content" /> 
+22
source

Found a solution by expanding SimpleDraweeView , it allows me to use wrap_content , and it works just fine! No matter how I prevent you from setting the size in setContentView , and the preview does not work, I would be glad if I could edit this answer to fix it.

Using

 <com.gazman.WrapContentDraweeView android:id="@+id/myImage" android:layout_width="wrap_content" android:layout_height="wrap_content" fresco:placeholderImage="@mipmap/myImage"/> 

Source

 public class WrapContentDraweeView extends SimpleDraweeView { private int outWidth; private int outHeight; public WrapContentDraweeView(Context context, GenericDraweeHierarchy hierarchy) { super(context, hierarchy); } public WrapContentDraweeView(Context context) { super(context); } public WrapContentDraweeView(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs); } public WrapContentDraweeView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context, attrs); } public WrapContentDraweeView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); init(context, attrs); } private void init(Context context, AttributeSet attrs) { if (attrs == null) { return; } TypedArray gdhAttrs = context.obtainStyledAttributes( attrs, R.styleable.GenericDraweeView); try { int placeholderId = gdhAttrs.getResourceId( R.styleable.GenericDraweeView_placeholderImage, 0); if(placeholderId != 0){ if(isInEditMode()){ setImageResource(placeholderId); } else { loadSize(placeholderId, context.getResources()); } } } finally { gdhAttrs.recycle(); } } private void loadSize(int placeholderId, Resources resources) { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(resources, placeholderId, options); outWidth = options.outWidth; outHeight = options.outHeight; } @Override public void setLayoutParams(ViewGroup.LayoutParams params) { params.width = outWidth; params.height = outHeight; super.setLayoutParams(params); } } 
0
source

In Kotlin, you can try something like this:

  val listener = object : BaseControllerListener<ImageInfo>() { override fun onFinalImageSet(id: String?, imageInfo: ImageInfo?, animatable: Animatable?) { super.onFinalImageSet(id, imageInfo, animatable) itemView.draweeGif.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT itemView.draweeGif.aspectRatio = (imageInfo?.width?.toFloat() ?: 0.toFloat()) / (imageInfo?.height?.toFloat() ?: 0.toFloat()) } } val controller = Fresco.newDraweeControllerBuilder() .setUri(uriGif) .setControllerListener(listener) .setAutoPlayAnimations(true) .build() itemView.draweeGif.controller = controller 

For me, this was a solution in my RecyclerView, because I was looking to set layoutParams directly in my ViewHolder.

0
source

All Articles