본문 바로가기

Android/Application

ViewPager 구현하기

ViewPager 구현하기




ViewPager(뷰 페이저). 좌우로 밀어내는 것으로 프레그먼트 이동이 쉽고, 이쁘기도 해서 카카오톡 등 앱들에서 많이 사용된다.

이번에는 바로 이 뷰 페이저를 만들어보자.



STEP1> 라이브러리 추가


compile 'com.ogaclejapan.smarttablayout:library:1.+@aar'


이름에서 알 수 있듯이, 이 라이브러리는 애니메이션이 아름다운 '탭'을 구현한 라이브러리다.

뷰 페이저는 안드로이드에서 제공하는 android.support.v4.view.ViewPager 사용한다.







STEP2> 뷰 작성



<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="kr.makerj.vmimic.fragment.main.MainActivityFragment">

<com.ogaclejapan.smarttablayout.SmartTabLayout
android:id="@+id/main_viewpagertab"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="#ff0000"
app:stl_indicatorAlwaysInCenter="false"
app:stl_indicatorWithoutPadding="false"
app:stl_indicatorInFront="false"
app:stl_indicatorInterpolation="smart"
app:stl_indicatorGravity="bottom"
app:stl_indicatorColor="#ffffff"
app:stl_indicatorThickness="4dp"
app:stl_indicatorCornerRadius="2dp"
app:stl_overlineColor="#4D000000"
app:stl_overlineThickness="0dp"
app:stl_underlineColor="#4D000000"
app:stl_underlineThickness="1dp"
app:stl_dividerColor="#4D000000"
app:stl_dividerThickness="1dp"
app:stl_defaultTabBackground="?attr/selectableItemBackground"
app:stl_defaultTabTextAllCaps="false"
app:stl_defaultTabTextColor="#ffffff"
app:stl_defaultTabTextSize="12sp"
app:stl_defaultTabTextHorizontalPadding="16dp"
app:stl_defaultTabTextMinWidth="0dp"
app:stl_distributeEvenly="true"
app:stl_clickable="true"
/>

<android.support.v4.view.ViewPager
android:id="@+id/main_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Fragments will be placed here -->
</android.support.v4.view.ViewPager>
</LinearLayout>


위와 같이 작성했다.

중요한 부분은 탭 뷰의

app:stl_defaultTabTextAllCaps="false"

로, 탭에 들어갈 문자열을 자동 대문자화 하는 옵션인데, 이게 탭에 아이콘을 활용하지 못하게 한다. 따라서 false로 변경한다.

나머지 옵션들은 이름에서 무슨 의미진지 유추 가능할 것이다.


android.support.v4.view.ViewPager는 딱히 설정할 게 없다. 이 뷰 페이저에는 실제 뷰인 프레그먼트들이 들어간다.


뷰 페이저 안에 들어갈 프레그먼트들은 알아서(...) 만들어두고, 다 만들었으면 STEP3로






STEP3> 뷰 페이저 어뎁터 설정



@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View layout = inflater.inflate(R.layout.fragment_main, container, false);

final List<_Fragment> fragments = new ArrayList<>();
fragments.add(HomeFragment.newInstance(null, null));
fragments.add(InterestFragment.newInstance());
fragments.add(PopularFragment.newInstance());
fragments.add(MyProfileFragment.newInstance());

FragmentPagerAdapter adapter = new FragmentPagerAdapter(getActivity().getSupportFragmentManager()) {
@Override
public CharSequence getPageTitle(int position) {
return fragments.get(position).getTitle(getActivity());
}

@Override
public Fragment getItem(int position) {
return fragments.get(position);
}

@Override
public int getCount() {
return fragments.size();
}
};

getActivity().setTitle(fragments.get(0).getTitle(getActivity()));
ViewPager pager = (ViewPager) layout.findViewById(R.id.main_viewpager);
pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}

@Override
public void onPageSelected(int position) {
getActivity().setTitle(fragments.get(position).getTitle(getActivity()));
}

@Override
public void onPageScrollStateChanged(int state) {
}
});
pager.setAdapter(adapter);
((SmartTabLayout) layout.findViewById(R.id.main_viewpagertab)).setViewPager(pager);

return layout;
}


나는 액티비티가 아니라, android.support.v4.app.Fragment프레그먼트. 즉 호환성 프레그먼트에 뷰 페이저를 넣어서 작성했다. 액티비티를 기반으로 개발하고 있다면 액티비티의 onCreate에 적용하자. 또한 호환성 라이브러리를 사용하고 있지 않다면 Support와 관련된 메소드를 사용하지 말 것.


코드를 순서대로 설명하자면,

  1. 프레그먼트 리스트 생성. 프레그먼트에 접근할 일이 많아서 리스트를 사용했다
  2. FragmentPagerAdapter생성 및 설정. PagerAdapter는 사용하지 않는다. 여기선 프레그먼트를 넣은 뷰 페이저를 사용할것이기 때문
  3. getPageTitle구현. 이게 있어야 탭이 타이틀을 인식한다. 반드시 구현할 것. 참고로 프레그먼트에 getTitle()메소드는 없다. 내가 만든거다. 적당히 제목을 반환하도록 만들자.
  4. getItem과 getCount를 구현한다. 리스트에 접근만 하면 되니. 딱히 할거 없다 위와 같이 구현하자.
  5. 페이지를 넘길 때, 적절히 액션바의 제목이 프레그먼트의 타이틀을 따라가도록 하자.
  6. getActivity().setTitle(fragments.get(0).getTitle(getActivity())) 초기값 설정. 첫 번째 페이지의 타이틀을 설정해주자.
  7. ViewPager.OnPageChangeListener의 onPageSelected를 작성한다. 이 코드가 페이지가 넘겨겼을 때 마다 액션바의 제목이 바뀌게 해준다.
  8. pager.setAdapter(adapter) 이제 뷰 페이저에 어뎁터를 설정해 주고,
  9. ((SmartTabLayout) layout.findViewById(R.id.뷰_페이저_아이디)).setViewPager(pager) 탭에 뷰 페이저를 설정해 주면 된다.







부록> 탭에 타이틀로 아이콘도 사용하고 싶다!



안드로이드는 보통 제목과 같은 문자열을 다룰 때, String이 아닌 CharSequence를 사용하고 있다.

안드로이드는 String같은 단순 문자열 뿐만 아니라 SpannableString과 같은 이미지를 포함한 문자열을 표현할 수 있다는 것을 잊지 말자.

따라서 return "프레그먼트1타이틀"과 같이 칙칙한 디자인을 유도하는 코드가 싫은 멋쟁이들은 아래와 같이 하자. 


public class ViewUtil {
public static int TEXT_SIZE = -1;
public static int TEXT_SIZE_BIG = -1;

public static Drawable drawable(Context context, int id) {
if (TEXT_SIZE == -1) {
TEXT_SIZE = (int) new TextView(context).getTextSize();
TEXT_SIZE_BIG = (int) (TEXT_SIZE * 1.5);
}
if (Build.VERSION.SDK_INT >= 21) {
return context.getResources().getDrawable(id, context.getTheme());
} else {
return context.getResources().getDrawable(id);
}
}

public static CharSequence iconText(Drawable icon, String text) {
SpannableString iconText = new SpannableString(" "+text);
icon.setBounds(0, 0, TEXT_SIZE_BIG, TEXT_SIZE_BIG);
ImageSpan imageSpan = new ImageSpan(icon);

iconText.setSpan(imageSpan, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return iconText;
}
}


많은 프레그먼트에서 호출될 테니, 아예 유틸리티 클래스로 작성했다. iconText에서 하는 일은 간단하다.

  1. SpannableString로 먼저 텍스트를 설정한다. 아이콘만 사용할 생각이라면 ""을 사용하자. 참고로 " " + text과 같이 한칸 띄어쓰기를 한 이유는, 한칸이 바로 아이콘의 자리이기 때문이다. 따라서 띄어쓰기 안하면 한 문자가 아이콘에 의해 가려진다.
  2. setBounds로 아이콘의 크기를 지정한다. 기본 문자열 크기의 1.5배가 적절하다
  3. 나머지 부분은 이미지 부분과 텍스트 부분을 합치는 것으로 큰 의미는 없다.


프레그먼트에서의 사용은?

public CharSequence getTitle(Context context) {
return ViewUtil.iconText(ViewUtil.drawable(context, R.drawable.ic_person_white_48dp), "MY");
}

프레그먼트에서의 사용은 이렇게 했다.





'Android > Application' 카테고리의 다른 글

Toolbar 사용하기  (0) 2015.09.24
프레그먼트에서 메뉴 사용하기  (0) 2015.09.24
Android SearchView  (0) 2015.09.23
안드로이드 상태바 색상 변경  (0) 2015.09.23
바코드, QR코드 생성  (0) 2015.09.22