안드로이드 개발을 하다보면 뷰페이저를 사용할 일이 많다.
뷰페이저를 사용하면 단순한 뷰 이동을 사용할 수 있고, 이로 인해 UI/UX가 좋아지게 되어 사용자 친화적인 앱을 만들 수 있기 때문이다.
처음 뷰페이저를 사용하는 사람들이 봉착하는 문제점 중 하나는, 갹 페이저들에 있는 위젯의 업데이트 관련 문제들이다. 실제로 나도 각각의 페이저들의 리사이클러뷰의 데이터가 변경되었거나, 텍스트뷰의 텍스트가 변경되었다던지.. 그럴 때 해당 페이저를 업데이트를 해줘야 하는데 그것이 잘 되지 않아서 해결 방법을 찾느라 한참 고생했던 기억이 있다.
1. FragmentPagerAdapter 를 상속한 커스텀 어댑터를 만들어서 getItemPosition 을 오버라이드 하여 아POSITION_NONE 구문을 넣는다. 아래의 어댑터 예시를 보자. MainFragmentPager는 Fragment를 상속하여 뷰페이저를 구성하는 부분이니 개인의 취향껏 구성하면 되겠다.
public class CustomFragmentPagerAdapter extends FragmentPagerAdapter {
private int MAX_PAGES;
public CustomFragmentPagerAdapter(FragmentManager fm, int maxPages) {
super(fm);
this.MAX_PAGES = maxPages;
}
@Override
public Fragment getItem(int position) {
if(position < 0 || MAX_PAGES <= position) {
return null;
}
return new MainFragmentPager(position);
}
@Override
public int getItemPosition(@NonNull Object object) {
return POSITION_NONE;
}
@Override
public int getCount() {
return MAX_PAGES;
}
}
2. 뷰페이저를 선언한 클래스에 ViewPager.OnPageChangeListener 를 implement 하면 onPageScrolled, onPageSelected, onPageScrollStateChanged 의 3개의 메서드를 오버라이드 해야 한다. onPageSelected에서 현재 보여지는 페이저의 뷰를 업데이트 하기 위한 코딩을 한다. 아래와 같이 해두면 된다.
@Override
public void onPageScrolled(int i, float v, int i1) {
}
@Override
public void onPageSelected(int position) {
switch (position) {
case 1:
refresh();
break;
}
}
@Override
public void onPageScrollStateChanged(int i) {
}
private void refresh() {
mCustomFragmentPagerAdapter.notifyDataSetChanged();
}
위와 같이 작업을 해두면, 내가 원하는 페이저 위치에 가면 뷰를 새롭게 업데이트하게 된다. 사실 POSITION_NONE 을 사용하면, 페이저에서 뷰가 삭제되었다고 강제로 알리게 되어 뷰를 새로 그리는 작업을 수행하기 때문에 약간 비효율적인 부분이 있다. 변경된 부분만 새로 그리게 되는 것이 아닌 전체를 새로 그리기 때문이다. 변경된 부분만 setTag 및 findViewWithTag를 통해서 그리는 것이 맞는데 생각보다 귀찮기도 하고.. 요즘 스마트폰의 성능이 워낙 좋기 때문에 위의 방법을 써도 크게 무리가 되지 않는다.