ViewPager 완전정복(탭 꾸미기)

Posted by ITPangPang
2016. 10. 31. 01:18 안드로이드(android)/ViewPager


ViewPager

완전정복(탭 꾸미기)



이번글은 분석은 아니고 ViewPager(Fragment)로

    탭 구조를 만들때, 상단에서 탭 역할을 맡은

    Button이나 TextView를 탭 처럼 꾸미는 방법

    대해 알아보도록 하겠습니다.


ㆍ 앞으로 글을 쓸 때, 화면이 못생기면 좀 할맛이 안날까봐.


shapeDrawableSelector 부분이므로 크게 설명할

    부분은 없으나, 클릭하거나 Swipe를 할 때 코드처리

    해야하는 부분이 있으므로 그 부분만 잠깐 보도록 하겠습니다.




막상 꾸미려고

하다보니.. 탭모양이 생각

안나서 카톡을 켜서..


본 후에 카톡 분위기처럼

만들어봤습니다



카톡탭은 이미지이므로

물론 다르겠지만.. 그냥

색깔 같은거만...



바로 꾸며보자


일단 선택했을때와

비선택했을때의 글자색깔이

다릅니다.


TextColor 부분을 만들겠습니다.


[drawable]-[tab_color_selector.xml]

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#301500" android:state_selected="true" />
<item android:color="#8C8C8C" />
</selector>



비선택(false)일때

background를 꾸며보겠습니다


[drawable]-[tab_bg_off]

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape android:shape="rectangle">
<padding
android:bottom="2dp"
/>
<solid android:color="#8C8C8C" />
</shape>
</item>

<item>
<shape android:shape="rectangle" >
<solid android:color="#EAEAEA" />
</shape>
</item>
</layer-list>


선택(true)일때

background 꾸며보겠습니다


[drawable]-[tab_bg_on]

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape android:shape="rectangle">
<padding
android:bottom="5dp"
/>
<solid android:color="#301500" />
</shape>
</item>

<item>
<shape android:shape="rectangle" >
<solid android:color="#EAEAEA" />
</shape>
</item>

</layer-list>


이제 완성된 on, off의

background를 선택됬을때와

아닐때를 구분할 수 있는 selector를

만들어보겠습니다


[drawable]-[tab_bg_selector]

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_selected="false"
android:drawable="@drawable/tab_bg_off" />
<item
android:state_selected="true"
android:drawable="@drawable/tab_bg_on" />
</selector>


준비가 완료되었으니

이제 layout에 그대로

추가시켜보겠습니다


[layout]-[activity_main]

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<LinearLayout
android:id="@+id/ll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/tab_first"
android:layout_width="0dip"
android:layout_height="50dp"
android:layout_weight="1"
android:gravity="center"
android:textColor="@drawable/tab_color_selector"
android:background=
"@drawable/tab_bg_selector"
android:text="친구" />

<TextView
android:id="@+id/tab_second"
android:layout_width="0dip"
android:layout_height="50dp"
android:layout_weight="1"
android:gravity="center"
android:textColor="@drawable/tab_color_selector"
android:background=
"@drawable/tab_bg_selector"
android:text="채팅방" />

<TextView
android:id="@+id/tab_third"
android:layout_width="0dip"
android:layout_height="50dp"
android:layout_weight="1"
android:gravity="center"
android:textColor="@drawable/tab_color_selector"
android:background=
"@drawable/tab_bg_selector"
android:text="설정" />
</LinearLayout>

<android.support.v4.view.ViewPager
android:id="@+id/vp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/ll">
</android.support.v4.view.ViewPager>

</RelativeLayout>


다 꾸몄으면 제대로 작동하도록 코드도 수정해보자


java파일은

이전글에서 사용하던


MainActivity.java

코드 그대로 가져와서

사용하되


탭을 선택하거나

Swipe를 했을때

setSelected 하는부분만

추가하였습니다


Fragment 파일의 코드는

이전글과 동일합니다.


[MainActivity.java]

public class MainActivity extends AppCompatActivity
{
ViewPager vp;
LinearLayout ll;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

vp = (ViewPager)findViewById(R.id.vp);
ll = (LinearLayout)findViewById(R.id.ll);

TextView tab_first = (TextView)findViewById(R.id.tab_first);
TextView tab_second = (TextView)findViewById(R.id.tab_second);
TextView tab_third = (TextView)findViewById(R.id.tab_third);

vp.setAdapter(new pagerAdapter(getSupportFragmentManager()));
vp.setCurrentItem(0);

tab_first.setOnClickListener(movePageListener);
tab_first.setTag(0);
tab_second.setOnClickListener(movePageListener);
tab_second.setTag(1);
tab_third.setOnClickListener(movePageListener);
tab_third.setTag(2);

tab_first.setSelected(true);

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

}

@Override
public void onPageSelected(int position)
{
int i = 0;
while(i<3)
{
if(position==i)
{
ll.findViewWithTag(i).setSelected(true);
}
else
{
ll.findViewWithTag(i).setSelected(false);
}
i++;
}
}

@Override
public void onPageScrollStateChanged(int state)
{

}
});
}


View.OnClickListener movePageListener = new View.OnClickListener()
{
@Override
public void onClick(View v)
{
int tag = (int) v.getTag();

int i = 0;
while(i<3)
{
if(tag==i)
{
ll.findViewWithTag(i).setSelected(true);
}
else
{
ll.findViewWithTag(i).setSelected(false);
}
i++;
}


vp.setCurrentItem(tag);
}
};

private class pagerAdapter extends FragmentStatePagerAdapter
{
public pagerAdapter(android.support.v4.app.FragmentManager fm)
{
super(fm);
}
@Override
public android.support.v4.app.Fragment getItem(int position)
{
switch(position)
{
case 0:
return new FirstFragment();
case 1:
return new SecondFragment();
case 2:
return new ThirdFragment();
default:
return null;
}
}
@Override
public int getCount()
{
return 3;
}
}
}


음 보기엔

길어보이지만

이번에 추가된 코드만

보면 얼마 안됩니다.


앱을 시작했을때 당연히

첫번째 탭이 선택되어있어야 하므로


tab_first.setSelected(true);

이 부분을

바로 추가해줬습니다


그리고

먼저 탭 선택했을때

처리과정을 보면

View.OnClickListener movePageListener = new View.OnClickListener()
{
@Override
public void onClick(View v)
{
int tag = (int) v.getTag();

int i = 0;
while(i<3)
{
if(tag==i)
{
ll.findViewWithTag(i).setSelected(true);
}
else
{
ll.findViewWithTag(i).setSelected(false);
}
i++;
}
vp.setCurrentItem(tag);
}
};


역시나 이전글과 마찬가지로

Tag를 활용해서 처리해봤습니다.

(Tag가 이해가 안가시는분은 이전글에

걸린 링크나 카테고리에서 View쪽에

있으니 한 번 봐주세요)


while문을 통하여

선택된 탭만 

setSelected(true) 처리하고

나머지 탭은

setSelected(false) 하는

부분입니다


혹시 위에처럼 Tag를 사용 안하시고

구현하시려면 각 버튼마다 따로 switch문으로

처리해주셔도 됩니다.


첫번째탭 눌렀을경우 :

tab_first.setSelected(true);

tab_second.setSelected(false);

tab_third.setSelected(false);

이런식으로..



다음은 Swipe 처리하는

코드를 보겠습니다.

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

}

@Override
public void onPageSelected(int position)
{
int i = 0;
while(i<3)
{
if(position==i)
{
ll.findViewWithTag(i).setSelected(true);
}
else
{
ll.findViewWithTag(i).setSelected(false);
}
i++;
}
}

@Override
public void onPageScrollStateChanged(int state)
{

}
});


addOnPageChangeListener라고

ViewPager 내부의 페이지 변화

있을때 호출되는 부분입니다.


이 리스너의 정확한 설명은

다시 날 잡아서 할 예정이기때문에

오늘은 onPageSelected쪽만 보면

될 것 같습니다.


말 그대로 페이지가 선택됬을때

호출되는 부분으로 postion값을 내뱉습니다


역시나

Tag(findViewWithTag)를 활용해서

처리하였습니다.


탭을 꾸미는 방법은

이것으로 마치겠습니다.


다음 글부터는

분석글로 돌아가서 

예고해드렸듯이


- setOffscreenPageLimit, setUserVisibleHint에 대해서


알아보도록 하겠습니다.