41

I'm new to Viewpager, and after reading http://developer.android.com/reference/android/support/v4/view/ViewPager.html from google, I can't seem to find anything related on viewPager.setOnItemClickListener(new OnItemClickListener() { Do we have other options to act as Item Clicked?

Testing out

viewPager.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                Intent i = new Intent(MainActivity.this, SingleItemView.class);
                i.putExtra("flag", flag);
                i.putExtra("position", position);
                startActivity(i);
            }

        });

Error : The method setOnItemClickListener(new AdapterView.OnItemClickListener(){}) is undefined for the type ViewPager

KC Chai
  • 1,607
  • 9
  • 30
  • 59

7 Answers7

92

There is no OnItemClick callback method for ViewPager. If you want click events on each page then you'll have to build your listener into the page content within your Adapter.

something like this:

@Override
public Object instantiateItem(View collection, final int pos) { //have to make final so we can see it inside of onClick()
    LayoutInflater inflater = (LayoutInflater) collection.getContext()
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);


    View page = inflater.inflate(R.layout.YOUR_PAGE, null);

    page.setOnClickListener(new OnClickListener(){
        public void onClick(View v){
            //this will log the page number that was click
            Log.i("TAG", "This page was clicked: " + pos);
        }
    });


    ((ViewPager) collection).addView(page, 0);
    return page;
}

exactly what you need will depend a bit on what else you are doing inside of instantiateItem() which you haven't posted so I can't give you a more specific answer.

Jayesh
  • 3,661
  • 10
  • 46
  • 76
FoamyGuy
  • 46,603
  • 18
  • 125
  • 156
  • Can we get the position out of the OnClick? – KC Chai May 03 '13 at 03:44
  • @DroidBeginner if by position you mean x/y then you'll have to use OnTouchListener() instead of onClick and get the x/y out of the MotionEvent that gets passed to onTouch() method. If you mean position as in which page the user was on then use just use the `int pos` parameter that is getting passed to instantiate item. I'll edit my answer to include the latter. – FoamyGuy May 03 '13 at 13:27
  • 3
    You guided me in the right direction. I put `onClickListener` on the `View` which was being returned in my Fragment's `onCreateView()`. – Sufian Jan 07 '15 at 07:27
  • 1
    instantiateItem IS DEPRICATED – Arpit Patel Nov 14 '16 at 08:10
  • @Arpit-patel since when? – X09 Apr 04 '17 at 08:25
  • How can we perform click action on the particular item on the page? – Shailendra Madda Aug 10 '18 at 13:00
41

I implemented custom ViewPager:

public class ClickableViewPager extends ViewPager {

    private OnItemClickListener mOnItemClickListener;

    public ClickableViewPager(Context context) {
        super(context);
        setup();
    }

    public ClickableViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        setup();
    }

    private void setup() {
        final GestureDetector tapGestureDetector = new    GestureDetector(getContext(), new TapGestureListener());

        setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                tapGestureDetector.onTouchEvent(event);
                return false;
            }
        });
    }

    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        mOnItemClickListener = onItemClickListener;
    }

    public interface OnItemClickListener {
        void onItemClick(int position);
    }

    private class TapGestureListener extends GestureDetector.SimpleOnGestureListener {

        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
            if(mOnItemClickListener != null) {
                mOnItemClickListener.onItemClick(getCurrentItem());
            }
            return true;
       }
    }
}

And code to implement onItemClickListener

ClickableViewPager viewPager = (ClickableViewPager) findViewById(R.id.viewPager);
viewPager.setOnItemClickListener(new ClickableViewPager.OnItemClickListener() {
            @Override
            public void onItemClick(int position) {
                // your code
            }
        });
idleberg
  • 12,634
  • 7
  • 43
  • 70
Volodymyr Yatsykiv
  • 3,181
  • 1
  • 24
  • 28
3

I'm not sure what you would be expecting to have respond to you with the above listener.

There is a setOnClickListener(View.OnClickListener l) that you can use to detect a touch to the viewPager.

You can also use onPageScrolled to get user input, and onPageSelected and onTabSelected.

@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}

@Override
public void onPageSelected(int position) {
    mActionBar.setSelectedNavigationItem(position);
}

@Override
public void onPageScrollStateChanged(int state) {
}

@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
    Object tag = tab.getTag();
    for (int i=0; i<mTabs.size(); i++) {
        if (mTabs.get(i) == tag) {
            mViewPager.setCurrentItem(i);
        }
    }
}
GrIsHu
  • 29,068
  • 10
  • 64
  • 102
HalR
  • 11,411
  • 5
  • 48
  • 80
3

in your activity; you can override :

 @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mDownX = ev.getX();
                mDownY = ev.getY();
                break;
            case MotionEvent.ACTION_UP:
                mDownX -= ev.getX();
                mDownY -= ev.getY();
                if(mDownX==0 && mDownY==0)
                   {
                      your action if click
                   }
                break;

        }
        return super.dispatchTouchEvent(ev);
    }
2

Use EventBus.

I just faced this problem with a simple solution just setting an OnClickListener at the adapter and then sending the Event.:

public Object instantiateItem(@NonNull ViewGroup container, int position) {
    LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View view = layoutInflater.inflate(R.layout.category_item_layout, container, false);
    ImageButton itemButton = view.findViewById(R.id.CategoryItem_ib_icon);
    itemButton.setOnClickListener(view1 -> EventBus.getDefault().postSticky(new Event(Constants.onViewPagerItem, position)));
    container.addView(view);
    return view;
}

The constructor:

    public Event(int code, int viewPagerPosition) {
    this.code = code;
    this.viewPagerPosition = viewPagerPosition;
}

Register the activity where you want to receive the Event:

EventBus.getDefault().register(this);

Later just receive the event with:

@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(Event event) {
    if (event.getCode() == Constants.onViewPagerItem) {
        Toast.makeText(getContext(), "Item " + event.getViewPagerPosition(), Toast.LENGTH_SHORT).show();
    }
}

Check it in case you don't know: https://github.com/greenrobot/EventBus

Hope it helps.

2
public Object instantiateItem(@NonNull final ViewGroup container, final int position)
{
    layoutInflater = LayoutInflater.from(context);
    View view = layoutInflater.inflate(R.layout.slide,container,false);
    ImageView image;
    TextView title,price;
    image = view.findViewById(R.id.image_id);
    title = view.findViewById(R.id.title_id);
    price = view.findViewById(R.id.price_id);
    image.setImageResource(slidePagers.get(position).getImage());
    title.setText((CharSequence) slidePagers.get(position).getTtile());
    price.setText((CharSequence) slidePagers.get(position).getPrice());
    view.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v)
        {
            if(position==0)
            {
                Intent intent = new Intent(context,getdata.class);
                context.startActivity(intent);
            }
            if(position==1)
            {
                Toast.makeText(context, "second Position", Toast.LENGTH_SHORT).show();
            }
            if(position==2)
            {
                Toast.makeText(context, "Third position ", Toast.LENGTH_SHORT).show();
            }

        }
    });
    container.addView(view,0);

    return view;
}
Aqif
  • 326
  • 3
  • 5
0

This is my solution :

 @Override
public Object instantiateItem(ViewGroup container, int position) {

    MainActivity.MainImageList list = imageLists.get(position);
    String image = list.getImage();

    ImageView imageView = new ImageView(context);
    imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);

    String webImage = context.getResources().getString(R.string.websiteCapsuleImages);
    Picasso.get().load(webImage + image).into(imageView);

    View page = imageView;

    page.setOnClickListener(new View.OnClickListener(){
        public void onClick(View v){
            //this will log the page number that was click
            Log.i("TAG", "This page was clicked: ");
        }
    });

    container.addView(imageView, 0);
    return imageView;



}