본문 바로가기

나의 플랫폼/안드로이드

[Android] TabLayout with ViewPager 에서 tab을 클릭 했을 때

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

TabLayout을 사용할 때, OnClickListener는 먹히지 않습니다. 

TabLayout의 자식뷰에 OnClickListener가 설정이 되지 않는 것이 원인 입니다.

(만약, addTab을 이용하여 추가할 경우 해당 View에 setTag,getTag로 구분으로 줘서 이용해도 될것이다.)


대부분 ViewPager와 TabLayout을 아래와 같이 설정 할 것이다.


FragmentPagerAdapter pagerAdapter = new FragmentPagerAdapter(getActivity().getSupportFragmentManager());

            TabLayout tabs = (TabLayout) mRootView.findViewById(R.id.tabLayout);

            ViewPager viewPager = (ViewPager) mRootView.findViewById(R.id.viewPager);

            viewPager .setAdapter( pagerAdapter );

            tabs .post(new Runnable() {

                @Override

                public void run() {

                    tabs .setupWithViewPager( viewPager );

                    tabs .setTabsFromPagerAdapter(pagerAdapter );

                    tabs .setOnTabSelectedListener(MainActivity.this);

                }

            });


            viewPager.addOnPageChangeListener(this);



참고로, setupWithViewPager, setTabsFromPagerAdapter, setOnTabSelectedListener 함수는 왜 post 안에 설정 했는지는 아래 포스트 내용을 참고 바란다.

http://gogorchg.tistory.com/entry/Android-Tablayout%EC%9D%B4-%EB%B3%B4%EC%9D%B4%EC%A7%80-%EC%95%8A%EC%9D%84-%EB%95%8C


이러면 아래 함수가 필요하게 되는데

@Override

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

        Log.d(getClass().getName(),"onPageScrolled : "+position);

    }


    @Override

    public void onPageSelected(int position) {

       Log.d(getClass().getName(),"onPageSelected : "+position);

    }


    @Override

    public void onPageScrollStateChanged(int state) {

Log.d(getClass().getName(),"onPageSelected : state);

    }


    @Override

    public void onTabSelected(TabLayout.Tab tab) {

        Log.d(getClass().getName(),"onTabSelected : "+tab.getPosition());

    }


ViewPager를 scroll 할때와 Tab을 터치했을 때 호출하는 pageScrollState 형태가 다릅니다.


## ViewPager에서 Scrolling 했을 때


onPageScrollStateChanged : 1

onPageScrollStateChanged : 2

onPageScrollStateChanged : 0

onTabSelected : 1



## TabLayout에서 선택 했을떄

onTabSelected : 1

onPageScrollStateChanged : 2

onPageScrollStateChanged : 0



위 내용에서 주의깊게 봐야 할 부분!!

1. onTabSelected가 먼저 호출 되는가?

2. onPageScrollStateChanged 에서 state 가 ViewPager.SCROLL_STATE_DRAGGING 상태가 되는가?


로써 구분이 가능 하다.


따라서, 아래와 같이 리스너를 체크하면 구분이 가능하게 된다.



boolean isDragged;

 ...


@Override

    public void onPageScrollStateChanged(int state) {

        if (state == ViewPager.SCROLL_STATE_DRAGGING)

            isDragged= true;

    }


    @Override

    public void onTabSelected(TabLayout.Tab tab) {

        if (!isDragged) {

// This is tab clicked

        }


        isDragged= false;

    }



isDragged Flag 값을 통하여 Dragging을 했는지 판단한 후, Dragging을 하지 않았을 때만 Tab이 Click 된걸로 간주 하면 됩니다.



## 참고 사항

위와 같이 사용할 때, 혹시 ViewPager의 Fragment에서 NullPointException이 발생하기도 합니다.

이럴 때는 아래와 같이 넣어보세요.


@Override

    public void onTabSelected(TabLayout.Tab tab) {

        if (!isDragged) {

               mViewPager.setCurrentItem(tab.getPosition());

        }


        isDragged= false;

    }



ViewPager의 Fragment가 아직 로딩이 되지 않은 상태일 경우가 발생할 때도 있기 때문입니다.

참고하세요.



## 이블로그는 어디까지는 찾았던 부분을 잊지 않기 위해 올려놓은 것 입니다.

    내용이 부실해도 이해해 주시길 바랍니다.