Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating buttons and button click under recyclerview item when it swiped (swip to dismiss) without using library

I am using RecyclerView for showing my list. I implement Swipe to dismiss on the RecyclerView with ItemTouchHelper. The underlying layout is implemented in OnchildDraw method by using canvas. Now I have a problem: I want to set onclick on my icon. By clicking on the icon, I want to do some functions. Here is My class:

public class ItemTouchHelperCallback : ItemTouchHelper.SimpleCallback
{
    private ContactSearchedResultAdapter _adapter;
    private RecyclerView _mRecyclerView;
    private int _swipeCount;
    private Android.Content.Res.Resources _resources;
    public ItemTouchHelperCallback(ContactSearchedResultAdapter adapter, RecyclerView mRecyclerView, Android.Content.Res.Resources resources)
        : base(0, ItemTouchHelper.Left | ItemTouchHelper.Right)
    {
        this._adapter = adapter;
        this._mRecyclerView = mRecyclerView;
        this._resources = resources;
    }
    public override bool OnMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target)
    {
        return false;
    }

    public override void OnSwiped(RecyclerView.ViewHolder viewHolder, int direction)
    {
        if (direction == ItemTouchHelper.Left)
        {
            _adapter.RemoveViewWithDialog(viewHolder.AdapterPosition, _mRecyclerView, _swipeCount);
            if (_swipeCount == 0)
                _swipeCount++;
        }
        else
        {
            _adapter.SaveContactToDataBase(viewHolder.AdapterPosition, _mRecyclerView);
        }
    }
    public override void OnChildDraw(Canvas cValue, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, bool isCurrentlyActive)
    {
        Paint paint = new Paint();
        View itemView = viewHolder.ItemView;
        float height = (float)itemView.Bottom - (float)itemView.Top;
        float width = height / 3;
        Bitmap icon;

        if (dX > 0)
        {
            paint.Color = Color.ParseColor("#388E3C");
            RectF background = new RectF((float)itemView.Left, (float)itemView.Top, dX, (float)itemView.Bottom);
            cValue.DrawRect(background, paint);
            icon = BitmapFactory.DecodeResource(_resources, Resource.Drawable.addoption);
            RectF icon_dest = new RectF((float)itemView.Left + width, (float)itemView.Top + width, (float)itemView.Left + 2 * width, (float)itemView.Bottom - width);
            cValue.DrawBitmap(icon, null, icon_dest, paint);
        }
        else
        {
            paint.Color = Color.ParseColor("#D32F2F");
            RectF background = new RectF((float)itemView.Right + dX, (float)itemView.Top, (float)itemView.Right, (float)itemView.Bottom);
            cValue.DrawRect(background, paint);
            icon = BitmapFactory.DecodeResource(_resources, Resource.Drawable.removeoption);
            RectF icon_dest = new RectF((float)itemView.Right - 2 * width, (float)itemView.Top + width, (float)itemView.Right - width, (float)itemView.Bottom - width);
            cValue.DrawBitmap(icon, null, icon_dest, paint);
        }

        float alpha = (float)1.0- Math.Abs(dX)/(float) itemView.Width;
        itemView.Alpha = alpha;
        itemView.TranslationX = dX;

        base.OnChildDraw(cValue, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
    }

}

As you can see I am calling ItemRemoving or ItemSaving in OnSwiped method. What I want to do now is calling these methods on icons' click (icons that are drawn by canvas in OnchildDraw) I searched a lot about this topic and couldn't find any solution that implemented this feature without using any library. I don't want to use library.

like image 700
Fahimeh Ebrahimi Avatar asked Aug 07 '16 06:08

Fahimeh Ebrahimi


2 Answers

I had the same problem as yours. I coded half a day and finally find one way.

First of all, I think this is android ItemTouchHelper problem that there are no methods to solve that.

So it can't use ItemTouchHelper and other system methods.

What I do is this: 1. Set recylerView.setOnTouchListener to get (x,y) on screen.

  1. When ItemTouchHelper onSwiped(), set it a state and find the clickable region.

  2. Check your touch point if it hits the icon region.

  3. Do something when hitted in your onTouch() method.

You can find my solution on my Github repo. https://github.com/TindleWei/WindGod

Here 3 ways to use ItemTouchHelper:

  1. android normal way like yours

  2. foregound and background region way

  3. viewpager way

On my repo, you can look at 2nd way.

like image 128
AdamWei Avatar answered Nov 15 '22 01:11

AdamWei


For those using AdamWei's solution number 2, if you're having trouble with the the recyclerview ontouchlistener in a fragment, change the following line:

Point point = new Point((int)motionEvent.getRawX(), (int)motionEvent.getRawY());

to

Point point = new Point((int) motionEvent.getX(), (int) motionEvent.getY());
like image 27
kabayaba Avatar answered Nov 14 '22 23:11

kabayaba