AMK
AMK

Reputation: 171

RecyclerView Swipe with a view below not detecting click

I have a RecyclerView row layout like this

<Layout>
    <BackgroundView>        
    <ForegroundView>
</Layout>

I am using ItemTouchHelper to handle swipes (partial) on the foreground view like

@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
    adapter.onItemSwiped(viewHolder);
}

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

    View foregroundView = ((myViewHolder)viewHolder).getForegroundView();
    getDefaultUIUtil().onDraw(c, recyclerView, foregroundView, dX, dY, actionState, isCurrentlyActive);

    //getSwipeLimit() used below returns the width of the delete icon
    float translationX = Math.min(-dX, ((myViewHolder) viewHolder).getSwipeLimit());
    foregroundView.setTranslationX(-translationX);
}

I have set a click listener for the backgroundview in the BindViewHolder of my adapter class.

@Override
public void onBindViewHolder(WhiteListViewHolder holder, Cursor cursor) {
    //get name and number from the cursor here

    holder.name.setText(name);
    holder.number.setText(number);

    holder.deleteButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Log.d("whitelist", "yes clicked");
        }
    });
}

The problem is, the background view is accepting clicks when the view is not swiped but after the view is swiped out, the background view stops accepting clicks.

enter image description here

Referring the above image, if I click on the delete button, the swiped view is recovered sometimes and it doesn't captures the click.

If I let the whole view swipe out, clicking the empty space left also brings back the swiped view.

Thanks in advance.

Upvotes: 17

Views: 4100

Answers (2)

IIIIIIIIIIIIIIIIIIIIII
IIIIIIIIIIIIIIIIIIIIII

Reputation: 4088

Had the same issue with ItemTouchHelper. Calling adapter.notifyDataSetChanged() in onSwiped(..) fixed the issue for me.

ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(0, LEFT) {
        override fun onMove(
            recyclerView: RecyclerView,
            viewHolder: RecyclerView.ViewHolder,
            target: RecyclerView.ViewHolder
        ): Boolean = false

        override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
            //calling my listeners here

            recycler_view.adapter?.notifyDataSetChanged()
        }

        override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
            if (viewHolder != null) {
                getDefaultUIUtil().onSelected(viewHolder.itemView.view_foreground)
            }
        }

        override fun onChildDrawOver(
            c: Canvas,
            recyclerView: RecyclerView,
            viewHolder: RecyclerView.ViewHolder?,
            dX: Float,
            dY: Float,
            actionState: Int,
            isCurrentlyActive: Boolean
        ) {
            if (dX < 0 && viewHolder != null) {
                getDefaultUIUtil().onDrawOver(
                    c,
                    recyclerView,
                    viewHolder.itemView.view_foreground,
                    dX,
                    dY,
                    actionState,
                    isCurrentlyActive
                )
            }
        }

        override fun onChildDraw(
            c: Canvas,
            recyclerView: RecyclerView,
            viewHolder: RecyclerView.ViewHolder,
            dX: Float,
            dY: Float,
            actionState: Int,
            isCurrentlyActive: Boolean
        ) {
            if (dX < 0) {
                getDefaultUIUtil().onDraw(
                    c,
                    recyclerView,
                    viewHolder.itemView.view_foreground,
                    dX,
                    dY,
                    actionState,
                    isCurrentlyActive
                )
            }
        }
    }).also {
        it.attachToRecyclerView(recycler_view)
    }

Upvotes: 2

dramf
dramf

Reputation: 271

I resolved the first part of the task - now did not detect without swipe. But the click do not detect after swipe...

 @Override
 public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
   if(actionState == ItemTouchHelper.ACTION_STATE_SWIPE){
     if (dX < 0) {
         backgroundView.setVisibility(View.VISIBLE);
     }
     else {
         backgroundView.setVisibility(View.GONE);
     }
   }
 }

Upvotes: 1

Related Questions