Skip to content

Commit

Permalink
Block item click callback during item layout.
Browse files Browse the repository at this point in the history
	Adding a RecyclerView.NO_POSITION != viewHolder.getAdapterPosition()
check inside of the click listener wrapper ensures we do not call the
click listener when the item is going through a layout.
	There was a need to make a change to the
ControllerLifecycleHelper to ensure that click still passed as the
adapter was always supplying `NO_POSITION` for unit tests. The simplest
way to get the basic functionality was to spy the viewHolder, and stub
this method.

ISSUE airbnb#293
  • Loading branch information
niccorder committed Oct 2, 2017
1 parent 3a77af2 commit a5c5646
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.airbnb.epoxy;

import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
Expand Down Expand Up @@ -54,7 +55,11 @@ public void onClick(View v) {
if (originalClickListener == null) {
throw new IllegalStateException("Long click listener was set.");
}
originalClickListener.onClick(model, object, v, holder.getAdapterPosition());

final int adapterPosition = holder.getAdapterPosition();
if (adapterPosition != RecyclerView.NO_POSITION) {
originalClickListener.onClick(model, object, v, adapterPosition);
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
import java.util.Collections;
import java.util.List;

import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;

class ControllerLifecycleHelper {
private EpoxyViewHolder viewHolder;

Expand Down Expand Up @@ -36,11 +39,16 @@ public View bindModel(EpoxyModel<?> model) {
}

static EpoxyViewHolder createViewHolder(BaseEpoxyAdapter adapter, int position) {
int itemViewType = adapter.getItemViewType(position);
return adapter.onCreateViewHolder(
new FrameLayout(RuntimeEnvironment.application),
itemViewType
final EpoxyViewHolder viewHolder = spy(
adapter.onCreateViewHolder(
new FrameLayout(RuntimeEnvironment.application),
adapter.getItemViewType(position)
)
);

// The simplest way to inject the position for testing.
when(viewHolder.getAdapterPosition()).thenReturn(position);
return viewHolder;
}

void recycleLastBoundModel(EpoxyController controller) {
Expand Down

0 comments on commit a5c5646

Please sign in to comment.