Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to know whether the page is selected from Swipe or Click of Tab of Viewpager

I have a ViewPager which Toolbar tabs.

I have to know how many times user clicked tabs and how many times user swiped and selected a page.

I am using ViewPager.OnPageChangeListener() for this purpose.

viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    @Override public void onPageSelected(int position) {
         // Here i am sending the GA event
    }

    @Override public void onPageScrollStateChanged(int state) {

    }
  });

OnPageSelected is called for both click and swipe of page. How will I differentiate the page selected is from click of tabs or its from swipe of Viewpager ?

like image 726
John Avatar asked Dec 16 '15 12:12

John


People also ask

How do I turn off swipe in ViewPager?

To enable / disable the swiping, just overide two methods: onTouchEvent and onInterceptTouchEvent . Both will return "false" if the paging was disabled. You just need to call the setPagingEnabled method with false and users won't be able to swipe to paginate.

How do I use tabLayout with ViewPager?

Tab layout are visible below toolbar with View pager, used to create swipeable views . Tabs are designed to work with fragments. Use them to swipe fragments in view pager.

How do I get ViewPager current position?

getChildAt(1); will return the current page. But, if you then change back to page 2 (from page 3) your list of children will be in this order page 2, page 3, page 1 which means that ViewPager. getChildAt(1); does not return the current page.


2 Answers

Here is my solution. I am basing on single variable.

public class MainActivity extends AppCompatActivity {

    // remember last action
    private Action lastAction = Action.RESET;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // ...

        mViewPager = findViewById(R.id.viewPager);
        mViewPager.setAdapter(mSectionsPagerAdapter);
        mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int i, float v, int i1) {
                // No-op
            }

            @Override
            public void onPageSelected(int i) {
                if (lastAction == Action.RESET) {
                    lastAction = Action.SWIPE;
                    Log.d(TAG, "onPageSelected: SWIPED");
                } else {
                    lastAction = Action.RESET;
                }
            }

            @Override
            public void onPageScrollStateChanged(int i) {
                // No-op
            }
        });

        mTabLayout = findViewById(R.id.tabLayout);
        mTabLayout.setupWithViewPager(mViewPager);
        mTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                if (lastAction == Action.RESET) {
                    lastAction = Action.SELECT;
                    Log.d(TAG, "onPageSelected: SELECTED");
                } else {
                    lastAction = Action.RESET;
                }
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                // No-op
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {
                // No-op
            }
        });
    }
}

Limitation:

Content for viewPager must be loaded before adding listeners because this solutions is basing on ordered calls (onTabSelected, onPageSelected).

Preview:

enter image description here

like image 67
deadfish Avatar answered Oct 01 '22 07:10

deadfish


In this example I will be checking if the user selected the page at index 1 by swiping or by tapping the tab:

Note: You can use tabLayout.getChildAt(0) to get the main sliding layout, and

((ViewGroup) tabLayout.getChildAt(0)).getChildAt(desiredPosition) //to get the tab at desired position

Using this, we add onClickListener to the desired tab and once clicked, its onClick() method will be called first followed by the onTabSelected() method of the TabSelectedListener of the TabLayout.

 private Boolean tabClicked = false; //variable which determines after entering the onTabSelected() method, if onClick was called or not

 ((ViewGroup) tabLayout.getChildAt(0)).getChildAt(1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                tabClicked = true;
            }
        });


  tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                if(tab.getPosition()==1){
                    if(tabClicked){ 
                         //your tab was clicked, do work here
                    }
                    else{ 
                         //your tab was swiped, do some work here
                    }
                    tabClicked = false;
                }
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {}

            @Override
            public void onTabReselected(TabLayout.Tab tab) {}

        });
like image 29
Aman Raj Sundram Avatar answered Oct 01 '22 09:10

Aman Raj Sundram