Sagar Trehan Sagar Trehan - 5 months ago 38
Android Question

Fresco Android lib: Not able to set hotspot on "overlayImage" drawable set in xml

I have set

app:overlayImage
drawable on
SimpleDraweeView
in
xml layout
for adding selector ripple effect on top of
SimpleDraweeView
. Setting
overlayImage
attribute correctly showing ripple effect on image but hot spot is always showing from center. To solve this I need the
overlayImage drawable
that I set in xml resource but I didn't find any method to get overlayImage drawable set to
SimpleDraweeView
resource programmatically.

If I prepare
GenericDraweeHierarchy
programmatically then I can prepare overlayImage drawable and can set touch listener hot spot to it. Code snippet:

SimpleDraweeView image = (SimpleDraweeView) findViewById(R.id.image);
GenericDraweeHierarchyBuilder builder = new GenericDraweeHierarchyBuilder(mContext.getResources());
Drawable overlayImage = getDrawable(R.drawable.image_selector);
builder.setOverlay(overlayImage);

image.setHierarchy(builder.build());

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
view.setOnTouchListener(new View.OnTouchListener() {

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public boolean onTouch(View v, MotionEvent event) {
if (overlayImage != null) {
overlayImage.setHotspot(event.getX(), event.getY());
}
return false;
}
});
}


But I do not want to create
GenericDraweeHierarchy
programmatically as I had already set different attributes in xml and do not want to change it and set programmatically. Please suggest any method to get
overlayImage
drawable that I had set in
xml layout
resource.

What I tried but did not work:


  1. Used
    getTopLevelDrawable()
    and
    getDrawable()
    method of
    SimpleDraweeView
    for getting
    drawable
    and
    setHotSpot
    to it.

  2. Used
    getTopLevelDrawable
    method of
    SimpleDraweeView
    after image
    loaded by setting ControllerListener to it and setting hotSpot to
    obtained drawable.



Please let me know if I can add hot spot in any other way.

Answer

I tried hard to add ripple overlay over Fresco SimpleDraweeView. I didn't find the exact solution for making ripple effect works properly on SimpleDraweeView, but I have come up with two approaches for adding working ripple effect:

  1. Wrap SimpleDraweeView inside FrameLayout and set android:foreground property to FrameLayout. Add android:clickable property to FrameLayout or add click listener to it. Code snippet:

    <FrameLayout
        android:id="@+id/image_container"
        android:layout_width="wrap_content"
        android:layout_height"wrap_content"
        android:foreground="@drawable/ripple_selector"
        android:clickable="true">
    
        <com.facebook.drawee.view.SimpleDraweeView
            android:id="@+id/image"
            android:layout_width="20dp"
            android:layout_height="20dp"/>
    
    </FrameLayout>
    

    Set clicklistener for FrameLayout container:

    findViewById(R.id.id/image_container).setOnClickListener(new View.OnClicklistener() {
            @Override
            public void onClick(View v) {
                // Do your stuff
            }
        })
    
  2. Extend SimpleDraweeView and draw ripple drawable on top of it. Following solution was provided by "boxcounter" on github. Check following link for Custom SimpleDraweeView that shows ripple effect on top of SimpleDraweeView.

I have reported same issue on Fresco library issue page. Hope it will get answered soon.

Fresco #912 issue update:

Few days back I provided a commit to Fresco which fix this issue. Now in com.facebook.fresco:fresco:0.11.0 we just need to set ripple drawable as value for app:overlayImage attribute and it will work perfectly.