Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 444
AMK Avatar asked Aug 28 '16 07:08

AMK


2 Answers

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);
     }
   }
 }
like image 131
dramf Avatar answered Sep 28 '22 06:09

dramf


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)
    }
like image 30
IIIIIIIIIIIIIIIIIIIIII Avatar answered Sep 28 '22 06:09

IIIIIIIIIIIIIIIIIIIIII