Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drag Shadow Using Item Touch Helper android

ItemTouchhelper Class in android helps only to move the entire view around the recyclerview. Is it possible to make a shadow of a view to be dragged(The original view to be in its place-fixed) using the Item touchHelper class?

like image 956
Jenison Gracious Avatar asked Feb 19 '16 13:02

Jenison Gracious


2 Answers

I overrode onChildDraw and made my own shadow

public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);

        if (isCurrentlyActive) {
            if (actionState == ItemTouchHelper.ACTION_STATE_DRAG) {
                // make shadown
                isRotated = true;
            }
        } else {
            // view is going back to orig
            if (isRotated) {
                // undo shadow
            }
        }
    }
like image 140
Martin Avatar answered Nov 04 '22 01:11

Martin


Here's a simple way to achieve shadow on the dragged item (for API >= 21 since it relies on elevation).

Declare an attribute in attrs.xml:

<attr name="draggedItemElevation" format="dimension"/>

Set the attribute value in your theme:

<style name="AppTheme" parent="...">
    <item name="draggedItemElevation">2dp</item>
</style>

Use this callback for the ItemTouchHelper:

class DragItemTouchHelperCallback : ItemTouchHelper.Callback() {

    // Get elevation in pixels from ?attr/draggedItemElevation.
    private val elevation = context.obtainStyledAttributes(
            intArrayOf(R.attr.editDraggedItemElevation)).use {
        it.getDimensionPixelSize(0, 0).toFloat()
    }

    override fun onChildDraw(c: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder,
                             dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean) {
        val view = viewHolder.itemView
        view.translationX = dX
        view.translationY = dY
        if (isCurrentlyActive) {
            ViewCompat.setElevation(view, elevation)
        }
    }

    override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {
        val view = viewHolder.itemView
        view.translationX = 0f
        view.translationY = 0f
        ViewCompat.setElevation(view, 0f)
    }

    override fun getMovementFlags(recyclerView: RecyclerView,
                                  viewHolder: RecyclerView.ViewHolder): Int {
        // ...
    }

    override fun onMove(recyclerView: RecyclerView,
                        viewHolder: RecyclerView.ViewHolder,
                        target: RecyclerView.ViewHolder): Boolean {
        // ...
    }

    override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
        // ...
    }
}

This will temporarily change the dragged item elevation to ?attr/draggedItemElevation, then set it back to 0 when the item is dropped.

like image 3
Nicolas Avatar answered Nov 04 '22 02:11

Nicolas