Released ViewPager2!

구글이 ViewPager를 2011년에 릴리즈한 이후로 새로운 버전인 ViewPager2(알파버전)를 릴리즈 했습니다. 
많은 개발자들이 페이지단위의 기능을 구현하기 위해 이 컴포넌트를 사용하고 있습니다. 

많은 개발자들이 사용한다고 해서 사용하기 쉬운 컴포넌트는 아닙니다. ViewPager를 만들기위해서는 Adapter도 구현해야하며, 어떤 어댑터를 구현해야할지 항상 고민하게 됩니다. FragmentPagerAdapter를 써야할지 또는  FragmentStatePagerAdapter써야하는지 말이죠. 그리고 Fragment를 꼭 사용해야하는지도…

아아.. 프레그먼트 생명주기…

New feature?

ViewPager와 비교하여 달라진 새로운기능

  • RTL 레이아웃 지원
  • 세로 모드 지원
  • 기존 ViewPager의 notifyDataSetChanged 버그 문제해결

기존에 가지고 있던 문제점으로는 Right-to-left(RTL) 레이아웃을 지원하지 않고, 세로모드 또한 없어서 여러 솔루션을 가진 라이브러리가 등장했었습니다. 그리고 notifyDataSetChanged()가 드디어 잘 작동합니다. 예전의 notifyDataSetChanged()는 page를 재생성하지 않았습니다. 가장 일반적인 회피방법이 getItemPosition을 재정의하여서 POSITION_NONE을 반환하는것이였죠.

의존성 추가

implementation 'androidx.viewpager2:viewpager2:1.0.0-alpha01'

ViewPager2 구현해보기

이미 RecyclerView가 친숙하다면, ViewPager2도 쉽게 친숙해질 수 있습니다. 
어댑터부터 만들어보죠.

class CheesePagerAdapter(private val cheeseStrings: Array<String>) : RecyclerView.Adapter<CheeseViewHolder>() {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CheeseViewHolder {
        return CheeseViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.cheese_list_item, parent, false))
    }

    override fun onBindViewHolder(holder: CheeseViewHolder, position: Int) {
        holder.cheeseName.text = cheeseStrings[position]
    }

    override fun getItemCount() = cheeseStrings.size
}

당연히 뷰홀더도 있어야겠죠

class CheeseViewHolder(view: View) : RecyclerView.ViewHolder(view) {

    val cheeseName: TextView = view.findViewById(R.id.cheese_name)
}

자 이제 어댑터의 인스턴스를 ViewPager2에 꽂아주기만 하면 준비는 끝납니다. 별도의 레이아웃 매니저를 만들어줄 필요는 없습니다. 

viewPager.adapter = CheesePagerAdapter(Cheeses.CheeseStrings)

 

세로모드도 되는지 확인해보죠.

viewPager.orientation = ViewPager2.ORIENTATION_VERTICAL

 

ViewPager2.class

public class ViewPager2 extends ViewGroup {
    ...
    private void initialize(Context context, AttributeSet attrs) {
        mRecyclerView = new RecyclerView(context) {
            ...
        };
        mRecyclerView.setId(ViewCompat.generateViewId());

        mLayoutManager = new LinearLayoutManager(context);
        mRecyclerView.setLayoutManager(mLayoutManager);
        setOrientation(context, attrs);

        mRecyclerView.setLayoutParams(
                new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        mRecyclerView.addOnChildAttachStateChangeListener(enforceChildFillListener());
        new PagerSnapHelper().attachToRecyclerView(mRecyclerView);
        ...
    }
    ...
    public final void setAdapter(@Nullable Adapter adapter) {
        mRecyclerView.setAdapter(adapter);
    }

   ...
}

전체코드를 확인할 순 없고 간단히 초기화 하는 코드만 보도록 하겠습니다. ViewPager2는 RecyclerView와 LayoutManager를 내부에서 품고 있기 때문에, 사실 일반적으로 우리가 쓰는 RecyclerView와 매우 흡사합니다. 기존 ViewPager처럼 페이지별로 스냅되는 기능을 추가하기위해 PageSnapHelper도 보입니다.

글을 쓰다보니 그냥 RecyclerView를 리뷰하는 느낌이 듭니다.

Summary

ViewPager2는 기존 ViewPager를 대체 할수 있는 훌륭한 대체제가 될것으로 기대됩니다. RecyclerView를 가지고 있으므로, RecyclerView가 가지고 있는 모든 기능을 쓸 수 있겠죠. notifyItemChanged(), notifyItemInserted() 메소드 그리고 DiffUtil도 쓸수 있겠네요. ItemDecoration이라던가 PageTransformer 까지 적용한다면 더 훌륭한 앱을 만들수 있을 것으로 기대됩니다.

카테고리: 미분류

0개의 댓글

답글 남기기

Avatar placeholder

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.