0

I am on Android Lollipop (minSdk=21), and want to implement moving a Floating Action Button around with a dragging gesture. The button is a custom subclass of ImageButton, the code is described here so I won't repeat it: Define default values for layout_width and layout_height properties for a subclass in a style

For dragging, I use the way described here: http://developer.android.com/guide/topics/ui/drag-drop.html. Here is what my code looks like:

    favoriteButton.setOnLongClickListener(new View.OnLongClickListener() {

        @Override
        public boolean onLongClick(View v) {
            v.startDrag(null, new View.DragShadowBuilder(v), null, 0);

            return true;
        }
    });

    findViewById(R.id.test_main_layout).setOnDragListener(new View.OnDragListener() {

        @Override
        public boolean onDrag(View v, DragEvent event) {
            switch (event.getAction()) {
                case DragEvent.ACTION_DRAG_ENTERED:
                    favoriteButton.setVisibility(View.INVISIBLE);
                    break;

                case DragEvent.ACTION_DROP:
                    favoriteButton.setX(event.getX() - favoriteButton.getWidth() / 2);
                    favoriteButton.setY(event.getY() - favoriteButton.getHeight() / 2);
                    favoriteButton.setVisibility(View.VISIBLE);
                    break;
            }

            return true;
        }
    });

Generally, it works, but the problem is the 'drag shadow': it is square. For this reason or the other, it doesn't respect the oval outline of the FAB.

How can I make it behave correctly?

Community
  • 1
  • 1
wujek
  • 10,112
  • 12
  • 52
  • 88

2 Answers2

1

I'd suggest implementing your own subclass of DragShadowBuilder: Only override onDrawShadow() and draw a circle of the size the FAB has. Then simply use that class in startDrag().

If your FAB is an ImageButton, you might already have an image you could use for the shadow, so that you don't even have to draw a circle. You could simply draw the same image to the Canvas in onDrawShadow(). Here is an example of how a shadow can be built from an image: https://gist.github.com/MarcinGil/5337109.

FD_
  • 12,947
  • 4
  • 35
  • 62
1

@FD_ thank you for your answer. In the meantime, while trying to ask something in a comment, I noticed that my background drawable used for the FAB is not an oval shape but rather a simple color:

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
        android:color="?android:attr/colorControlHighlight">

    <item android:drawable="?android:attr/colorAccent"/>

</ripple>

After changing it to this:

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
        android:color="?android:attr/colorControlHighlight">

    <item android:drawable="@drawable/oval_accent_drawable"/>

</ripple>

with another oval drawable with the wanted color:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="oval">

    <solid android:color="?android:attr/colorAccent"/>

    <size
        android:width="@dimen/fab_size"
        android:height="@dimen/fab_size"/>

</shape>

the drag shadow now works perfectly.

Thank you for being my rubber duck.

wujek
  • 10,112
  • 12
  • 52
  • 88