Search code examples
androidandroid-layoutfresco

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.


Solution

  • 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.