I have a ViewPager inside every row of a ListView. It works fine, it changes the views inside it when the user use the swipe gesture, but it prevents the ListView\'s onItemC
The idea is to do the click listener on the view pager and not the listView
When adding the viewPager in the getView method, set its tag to be the position of the row
holder.viewPager.setTag(position);
Then add the click listener to the viewPager (also in getView)
viewPager.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
int position = v.getTag();
Log.d(TAG, "onItemClick: " + position);
//Fire a delegate or notification of whatever you want to do on the item click. You now have the position
myClickListener.onItemClicked(position);
}
});
I think this should do the trick.
viewPager.getParent().requestDisallowInterceptTouchEvent(false);
I hope this will help you.
This is what I've done finally to manage this although the list selector doesn't work. This could be improved, but, for now, it is the only workaround that I like how it works.
public class CustomListView extends ListView implements AbsListView.OnScrollListener {
/*
* Used for detect taps
*/
private GestureDetector tapDetector;
/*
* As we need to set our own OnScrollListener, this stores the one
* used outside, if any
*/
private OnScrollListener onScrollListener;
private boolean isScrolling = false;
public CustomListView(Context context) {
super(context);
initView(context);
}
public CustomListView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}
public CustomListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public CustomListView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
initView(context);
}
private void initView(Context context) {
tapDetector = new GestureDetector(context, new TapListener());
super.setOnScrollListener(this);
}
@Override
public void setOnScrollListener(OnScrollListener onScrollListener) {
this.onScrollListener = onScrollListener;
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
boolean isTap = tapDetector.onTouchEvent(ev);
if(ev.getActionMasked() == MotionEvent.ACTION_UP) {
// Don't perform the click if the ListView is scrolling
// so it is able to stop the scroll
if(isTap && !isScrolling && hasOnItemClickListener()) {
int itemPosition = pointToPosition((int)ev.getX(), (int)ev.getY());
performItemClick(this, itemPosition, getItemIdAtPosition(itemPosition));
}
}
return super.dispatchTouchEvent(ev);
}
public boolean hasOnItemClickListener() {
return getOnItemClickListener() != null;
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
isScrolling = scrollState != OnScrollListener.SCROLL_STATE_IDLE;
if(this.onScrollListener != null) {
onScrollListener.onScrollStateChanged(view, scrollState);
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if(this.onScrollListener != null) {
onScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
}
}