ViewPager에서 ViewPager2로 이전

ViewPager2ViewPager 라이브러리의 개선된 버전입니다. 향상된 기능을 제공하고 ViewPager 사용과 관련된 일반적인 문제를 해결합니다. 앱에서 이미 ViewPager를 사용하고 있다면 이 페이지에서 자세히 알아보세요. ViewPager2로 이전하는 중입니다.

앱에서 ViewPager2 사용을 원하며 현재 사용하고 있지 않은 경우 ViewPager, 다음을 사용하여 프래그먼트 간 슬라이드하기 ViewPager2다음으로 스와이프 뷰 만들기 자세한 내용은 ViewPager2를 사용하는 탭에서 확인하세요. 확인할 수 있습니다

ViewPager2로 이전하여 얻을 수 있는 이점

이전하는 주된 이유는 ViewPager2이(가) 활성 상태이기 때문입니다. 개발 지원을 사용하고 ViewPager는 그렇지 않습니다. 그 외에도 ViewPager2에서 다음을 제공합니다. 기타 몇 가지 구체적인 장점이 있습니다

수직 방향 지원

ViewPager2는 기존 가로 페이지 외에도 세로 페이징을 지원합니다. 페이징 다음을 설정하여 ViewPager2 요소의 세로 페이징을 사용 설정할 수 있습니다. android:orientation 속성:

<androidx.viewpager2.widget.ViewPager2
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:orientation="vertical" />

또한 setOrientation() 메서드를 사용하여 축소하도록 요청합니다.

오른쪽에서 왼쪽 지원

ViewPager2는 오른쪽에서 왼쪽(RTL) 페이징을 지원합니다. RTL 페이징이 사용 설정되었습니다. 언어에 따라 적절한 경우 자동으로 동기화되지만, 수동으로 다음을 설정하여 ViewPager2 요소에 RTL 페이징을 사용 설정합니다. android:layoutDirection 속성:

<androidx.viewpager2.widget.ViewPager2
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:layoutDirection="rtl" />

또한 setLayoutDirection() 메서드를 사용하여 축소하도록 요청합니다.

수정 가능한 프래그먼트 컬렉션

ViewPager2는 수정 가능한 프래그먼트 컬렉션을 통해 페이징을 지원합니다. 통화 notifyDatasetChanged() 기본 컬렉션이 변경될 때 UI를 업데이트합니다.

즉, 앱이 프래그먼트 컬렉션을 동적으로 수정할 수 있으므로 ViewPager2는 수정된 컬렉션을 올바르게 표시합니다.

DiffUtil

ViewPager2RecyclerView에 기반합니다. 즉, GCP 리소스에 대한 DiffUtil 유틸리티 클래스에 대해 자세히 알아보세요. 이렇게 하면 여러 가지 이점이 있지만, 무엇보다도 ViewPager2 객체는 기본적으로 데이터 세트 변경 애니메이션을 활용함 RecyclerView 클래스에서 파생됩니다.

ViewPager2로 앱 이전

앱의 ViewPager 객체를 ViewPager2로 업데이트하려면 다음 단계를 따르세요.

XML 레이아웃 파일 업데이트

먼저 XML 레이아웃 파일의 ViewPager 요소를 ViewPager2 요소:

<!-- A ViewPager element -->
<android.support.v4.view.ViewPager
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

<!-- A ViewPager2 element -->
<androidx.viewpager2.widget.ViewPager2
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

어댑터 클래스 업데이트

ViewPager를 사용할 때는 가 객체에 새 페이지를 제공했습니다. ViewPager는 사용 사례에 따라 세 가지 추상 클래스입니다. ViewPager2는 두 가지 추상 클래스만 사용합니다.

ViewPager2 객체로 변환하는 ViewPager 객체마다 다음과 같이 어댑터 클래스를 업데이트하여 적절한 추상 클래스를 확장합니다.

생성자 매개변수

FragmentPagerAdapter에서 상속되는 프래그먼트 기반 어댑터 클래스 또는 FragmentStatePagerAdapter는 항상 단일 FragmentManager 객체를 허용합니다. 생성자 매개변수로 전달하세요. FragmentStateAdapter 확장 시 ViewPager2 어댑터 클래스에서는 생성자에 다음과 같은 옵션이 있습니다. 매개변수를 사용하세요.

  • FragmentActivity 객체 또는 Fragment 객체. 여기서 ViewPager2 객체가 상주합니다. 대부분의 경우 이 옵션을 사용하는 것이 더 좋습니다.
  • FragmentManager 객체 및 Lifecycle 객체.

RecyclerView.Adapter에서 직접 상속되는 뷰 기반 어댑터 클래스 생성자 매개변수가 필요하지 않습니다.

메서드 재정의

어댑터 클래스는 ViewPager2의 다른 메서드도 재정의해야 합니다. 더 높은 ViewPager:

  • getCount()가 아닌 getItemCount()를 재정의합니다. 이름 외에 이 메서드는 변경되지 않습니다.
  • 프래그먼트 기반에서 getItem() 대신 createFragment()를 재정의합니다. 어댑터 클래스. 새 createFragment() 메서드가 항상 는 함수가 호출될 때마다 대신 새 프래그먼트 인스턴스를 제공합니다. 할 수 있습니다
를 통해 개인정보처리방침을 정의할 수 있습니다.

요약

요약하면 ViewPager2와 함께 사용할 ViewPager 어댑터 클래스를 변환하려면 다음 안내를 따르세요. 다음과 같이 변경해야 합니다.

  1. 뷰를 페이징하기 위해 슈퍼클래스를 RecyclerView.Adapter로 변경합니다. FragmentStateAdapter: 프래그먼트를 통한 페이징용
  2. 프래그먼트 기반 어댑터 클래스에서는 생성자 매개변수를 변경합니다.
  3. getCount()가 아닌 getItemCount()를 재정의합니다.
  4. 프래그먼트 기반 어댑터에서 getItem() 대신 createFragment()를 재정의합니다. 있습니다.

Kotlin

// A simple ViewPager adapter class for paging through fragments
class ScreenSlidePagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) {
    override fun getCount(): Int = NUM_PAGES

    override fun getItem(position: Int): Fragment = ScreenSlidePageFragment()
}

// An equivalent ViewPager2 adapter class
class ScreenSlidePagerAdapter(fa: FragmentActivity) : FragmentStateAdapter(fa) {
    override fun getItemCount(): Int = NUM_PAGES

    override fun createFragment(position: Int): Fragment = ScreenSlidePageFragment()
}

자바

// A simple ViewPager adapter class for paging through fragments
public class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
    public ScreenSlidePagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        return new ScreenSlidePageFragment();
    }

    @Override
    public int getCount() {
        return NUM_PAGES;
    }
}

// An equivalent ViewPager2 adapter class
private class ScreenSlidePagerAdapter extends FragmentStateAdapter {
    public ScreenSlidePagerAdapter(FragmentActivity fa) {
        super(fa);
    }

    @Override
    public Fragment createFragment(int position) {
        return new ScreenSlidePageFragment();
    }

    @Override
    public int getItemCount() {
        return NUM_PAGES;
    }
}

TabLayout 인터페이스 리팩터링

ViewPager2에서는 TabLayout 통합이 변경되었습니다. 만약 현재 TabLayout 객체와 함께 ViewPager를 사용하여 가로 방향 표시 TabLayout 객체를 리팩터링해야 하며 ViewPager2 통합

TabLayoutViewPager2에서 분리되었으며 이제 Material 구성요소 즉, 사용하려면 태그에 build.gradle 파일에 적절한 종속 항목을 추가합니다.

Groovy

implementation "com.google.android.material:material:1.1.0-beta01"

Kotlin

implementation("com.google.android.material:material:1.1.0-beta01")

계층 구조에서 TabLayout 요소의 위치도 변경해야 합니다. XML 레이아웃 파일입니다. ViewPager를 사용하면 TabLayout 요소가 다음으로 선언됩니다. ViewPager 요소의 하위 요소 그러나 ViewPager2를 사용하면 TabLayout 요소가 같은 수준에서 ViewPager2 요소 바로 위에 선언됩니다.

<!-- A ViewPager element with a TabLayout -->
<androidx.viewpager.widget.ViewPager
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</androidx.viewpager.widget.ViewPager>

<!-- A ViewPager2 element with a TabLayout -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

</LinearLayout>

마지막으로 TabLayout 객체를 ViewPager 객체. TabLayout는 자체 setupWithViewPager()를 사용합니다. ViewPager와 통합하려면 TabLayoutMediator가 필요합니다. ViewPager2과(와) 통합할 수 있습니다.

TabLayoutMediator 객체는 페이지 제목 생성 작업도 처리합니다. TabLayout 객체의 경우, 어댑터 클래스가 다음과 같이 getPageTitle()를 재정의합니다.

Kotlin

// Integrating TabLayout with ViewPager
class CollectionDemoFragment : Fragment() {
    ...
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        val tabLayout = view.findViewById(R.id.tab_layout)
        tabLayout.setupWithViewPager(viewPager)
    }
    ...
}

class DemoCollectionPagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) {

    override fun getCount(): Int  = 4

    override fun getPageTitle(position: Int): CharSequence {
        return "OBJECT ${(position + 1)}"
    }
    ...
}

// Integrating TabLayout with ViewPager2
class CollectionDemoFragment : Fragment() {
    ...
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        val tabLayout = view.findViewById(R.id.tab_layout)
        TabLayoutMediator(tabLayout, viewPager) { tab, position ->
            tab.text = "OBJECT ${(position + 1)}"
        }.attach()
    }
    ...
}

자바

// Integrating TabLayout with ViewPager
public class CollectionDemoFragment extends Fragment {
    ...
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        TabLayout tabLayout = view.findViewById(R.id.tab_layout);
        tabLayout.setupWithViewPager(viewPager);
    }
    ...
}

public class DemoCollectionPagerAdapter extends FragmentStatePagerAdapter {
    ...
    @Override
    public int getCount() {
        return 4;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return "OBJECT " + (position + 1);
    }
    ...
}

// Integrating TabLayout with ViewPager2
public class CollectionDemoFragment : Fragment() {
    ...
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        TabLayout tabLayout = view.findViewById(R.id.tab_layout);
        new TabLayoutMediator(tabLayout, viewPager,
                (tab, position) -> tab.setText("OBJECT " + (position + 1))
        ).attach();
    }
    ...
}

중첩된 스크롤 가능 요소 지원

ViewPager2는 다음과 같은 경우 기본적으로 중첩 스크롤 뷰를 지원하지 않습니다. 스크롤 뷰는 다음 항목이 포함된 ViewPager2 객체와 방향이 동일합니다. 있습니다. 예를 들어 세로 스크롤 뷰에서는 스크롤이 작동하지 않습니다. 세로 방향 ViewPager2 객체를 사용합니다.

동일한 방향의 ViewPager2 객체 내에서 스크롤 뷰를 지원하려면 너는 반드시 다음과 같은 경우 ViewPager2 객체에 대한 requestDisallowInterceptTouchEvent() 대신 중첩된 요소를 스크롤할 수 있습니다. ViewPager2 중첩 스크롤 샘플은 다목적으로 이 문제를 해결하는 한 가지 방법을 보여줍니다. 맞춤 래퍼 레이아웃을 제공합니다.

추가 리소스

ViewPager2에 관해 자세히 알아보려면 다음 추가 리소스를 참조하세요.

샘플

동영상