화면 슬라이드는 전체 화면에서 다른 화면으로의 전환이며
설치 마법사 및 슬라이드쇼가 포함됩니다. 이 주제에서는 Cloud Build를 사용하여
ViewPager2
객체를 지정합니다. ViewPager2
객체는 화면 슬라이드에 자동으로 애니메이션을 적용할 수 있습니다. 예를 들면 다음과 같습니다.
다음 콘텐츠 화면에서 다음 화면으로 전환하는 화면 슬라이드의 예입니다.
이를 건너뛰고 실제로 완벽히 작동하는 예를 보려면 보기 이 샘플 앱을 참고하세요.
<ph type="x-smartling-placeholder">ViewPager2
기능을 사용하려면
AndroidX 종속 항목을
살펴보겠습니다 그런 다음 아래 섹션에 설명된 단계를 따릅니다.
뷰 만들기
나중에 프래그먼트의 콘텐츠에 사용할 레이아웃 파일을 만듭니다. 문자열도 함께 정의해야 합니다. 를 사용합니다. 다음 예에는 텍스트:
<!-- fragment_screen_slide_page.xml --> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/content" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView style="?android:textAppearanceMedium" android:padding="16dp" android:lineSpacingMultiplier="1.2" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/lorem_ipsum" /> </ScrollView>
프래그먼트 만들기
만들기
Fragment
클래스를 사용하는
는
onCreateView()
메서드를 사용하여 축소하도록 요청합니다. 그런 다음, 이 프래그먼트의 인스턴스가 필요할 때마다 상위 활동에서 이 프래그먼트의 인스턴스를 생성할 수 있습니다.
새 페이지가 표시됩니다.
Kotlin
import androidx.fragment.app.Fragment class ScreenSlidePageFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View = inflater.inflate(R.layout.fragment_screen_slide_page, container, false) }
자바
import androidx.fragment.app.Fragment; ... public class ScreenSlidePageFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return (ViewGroup) inflater.inflate( R.layout.fragment_screen_slide_page, container, false); } }
ViewPager2 추가
ViewPager2
객체에는 페이지 간에 전환하는 스와이프 동작이 내장되어 있습니다.
기본적으로 화면 슬라이드 애니메이션을 표시하므로 직접 애니메이션을 만들 필요가 없습니다.
ViewPager2
사용
FragmentStateAdapter
객체를 새 페이지의 공급 장치로 사용하므로 FragmentStateAdapter
는
프래그먼트 클래스를 표시합니다.
시작하려면 ViewPager2
객체가 포함된 레이아웃을 만듭니다.
<!-- activity_screen_slide.xml --> <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" />
다음을 실행하는 활동을 만듭니다.
- 콘텐츠 뷰를
ViewPager2
가 있는 레이아웃으로 설정합니다. FragmentStateAdapter
추상 클래스를 확장하는 클래스를 만듭니다. 는createFragment()
메서드를 사용하여ScreenSlidePageFragment
의 인스턴스를 새 페이지로 제공합니다. 다음을 수행해야 합니다. 구현하고getItemCount()
페이저 어댑터의 메서드를 호출합니다. 이 메서드는 어댑터가 만든 페이지 수를 반환합니다. 현재 예를 들면 5입니다.FragmentStateAdapter
를ViewPager2
객체에 연결합니다.
Kotlin
import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity ... /** * The number of pages (wizard steps) to show in this demo. */ private const val NUM_PAGES = 5 class ScreenSlidePagerActivity : FragmentActivity() { /** * The pager widget, which handles animation and allows swiping horizontally * to access previous and next wizard steps. */ private lateinit var viewPager: ViewPager2 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_screen_slide) // Instantiate a ViewPager2 and a PagerAdapter. viewPager = findViewById(R.id.pager) // The pager adapter, which provides the pages to the view pager widget. val pagerAdapter = ScreenSlidePagerAdapter(this) viewPager.adapter = pagerAdapter } override fun onBackPressed() { if (viewPager.currentItem == 0) { // If the user is currently looking at the first step, allow the system to handle // the Back button. This calls finish() on this activity and pops the back stack. super.onBackPressed() } else { // Otherwise, select the previous step. viewPager.currentItem = viewPager.currentItem - 1 } } /** * A simple pager adapter that represents 5 ScreenSlidePageFragment objects, in * sequence. */ private inner class ScreenSlidePagerAdapter(fa: FragmentActivity) : FragmentStateAdapter(fa) { override fun getItemCount(): Int = NUM_PAGES override fun createFragment(position: Int): Fragment = ScreenSlidePageFragment() } }
자바
import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; ... public class ScreenSlidePagerActivity extends FragmentActivity { /** * The number of pages (wizard steps) to show in this demo. */ private static final int NUM_PAGES = 5; /** * The pager widget, which handles animation and allows swiping horizontally to access previous * and next wizard steps. */ private ViewPager2 viewPager; /** * The pager adapter, which provides the pages to the view pager widget. */ private FragmentStateAdapter pagerAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_screen_slide); // Instantiate a ViewPager2 and a PagerAdapter. viewPager = findViewById(R.id.pager); pagerAdapter = new ScreenSlidePagerAdapter(this); viewPager.setAdapter(pagerAdapter); } @Override public void onBackPressed() { if (viewPager.getCurrentItem() == 0) { // If the user is currently looking at the first step, allow the system to handle the // Back button. This calls finish() on this activity and pops the back stack. super.onBackPressed(); } else { // Otherwise, select the previous step. viewPager.setCurrentItem(viewPager.getCurrentItem() - 1); } } /** * A simple pager adapter that represents 5 ScreenSlidePageFragment objects, in * sequence. */ 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; } } }
PageTransformer를 사용하여 애니메이션 맞춤설정
기본 화면 슬라이드 애니메이션과 다른 애니메이션을 표시하려면
ViewPager2.PageTransformer
인터페이스를 만들고 ViewPager2
객체에 제공합니다. 인터페이스는 단일 포드를 노출하고
메서드를 사용하면
transformPage()
화면 전환의 각 지점에서 이 메서드는 표시되는 페이지마다 한 번씩 호출됩니다.
대개 화면 밖에 있는 인접 페이지에 대해서만 표시됩니다. 예를 들어 세 번째 페이지가
표시되고 사용자가 4페이지로 드래그하면 2페이지에 transformPage()
가 호출됩니다.
동작의 각 단계에서 3개, 4개의 동작을 취합니다.
그런 다음 transformPage()
구현에서 맞춤 슬라이드를 만들 수 있습니다.
페이지의 위치에 따라 변환해야 할 페이지를 결정하여 애니메이션을 적용합니다.
화면 position
매개변수에서 페이지 위치를 가져옵니다.
transformPage()
메서드를 사용하여 지도 가장자리에
패딩을 추가할 수 있습니다.
position
매개변수는
화면 중앙에 오도록 합니다. 이 매개변수는 사용자가 스크롤할 때 변경되는 동적 속성입니다.
생성할 수 있습니다. 페이지가 화면을 채우면 위치 값은 0
입니다. 페이지에서
이 화면 오른쪽에서 벗어나면 위치 값은 1
입니다. 사용자가 스크롤하는 경우
1페이지와 2페이지 사이 중간 지점에 위치했으며 1페이지의 게재순위는 -0.5
이며 2페이지의 위치는
0.5
의 게재순위 화면의 페이지 위치에 따라
다음과 같은 메서드로 페이지 속성을 설정하여 맞춤 슬라이드 애니메이션을 만들 수 있습니다.
setAlpha()
,
setTranslationX()
,
또는
setScaleY()
입니다.
Google 게시자 태그 구현 시
PageTransformer
,
통화
setPageTransformer()
맞춤 애니메이션을 적용할 수 있습니다. 예를 들어
이름이 ZoomOutPageTransformer
인 PageTransformer
입니다. 커스텀
다음과 같습니다.
Kotlin
val viewPager: ViewPager2 = findViewById(R.id.pager) ... viewPager.setPageTransformer(ZoomOutPageTransformer())
자바
ViewPager2 viewPager = findViewById(R.id.pager); ... viewPager.setPageTransformer(new ZoomOutPageTransformer());
페이지 축소 변환기를 참조하세요.
심도 페이지 변환기 섹션에서
PageTransformer
입니다.
페이지 축소 변환기
이 페이지 변환기는 인접 페이지 사이를 스크롤할 때 페이지를 축소하고 페이드 아웃합니다. 페이지 형식 중앙에 가까워지면 원래 크기로 다시 커졌다가 페이드인됩니다.
Kotlin
private const val MIN_SCALE = 0.85f private const val MIN_ALPHA = 0.5f class ZoomOutPageTransformer : ViewPager2.PageTransformer { override fun transformPage(view: View, position: Float) { view.apply { val pageWidth = width val pageHeight = height when { position < -1 -> { // [-Infinity,-1) // This page is way off-screen to the left. alpha = 0f } position <= 1 -> { // [-1,1] // Modify the default slide transition to shrink the page as well. val scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position)) val vertMargin = pageHeight * (1 - scaleFactor) / 2 val horzMargin = pageWidth * (1 - scaleFactor) / 2 translationX = if (position < 0) { horzMargin - vertMargin / 2 } else { horzMargin + vertMargin / 2 } // Scale the page down (between MIN_SCALE and 1). scaleX = scaleFactor scaleY = scaleFactor // Fade the page relative to its size. alpha = (MIN_ALPHA + (((scaleFactor - MIN_SCALE) / (1 - MIN_SCALE)) * (1 - MIN_ALPHA))) } else -> { // (1,+Infinity] // This page is way off-screen to the right. alpha = 0f } } } } }
자바
public class ZoomOutPageTransformer implements ViewPager2.PageTransformer { private static final float MIN_SCALE = 0.85f; private static final float MIN_ALPHA = 0.5f; public void transformPage(View view, float position) { int pageWidth = view.getWidth(); int pageHeight = view.getHeight(); if (position < -1) { // [-Infinity,-1) // This page is way off-screen to the left. view.setAlpha(0f); } else if (position <= 1) { // [-1,1] // Modify the default slide transition to shrink the page as well. float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position)); float vertMargin = pageHeight * (1 - scaleFactor) / 2; float horzMargin = pageWidth * (1 - scaleFactor) / 2; if (position < 0) { view.setTranslationX(horzMargin - vertMargin / 2); } else { view.setTranslationX(-horzMargin + vertMargin / 2); } // Scale the page down (between MIN_SCALE and 1). view.setScaleX(scaleFactor); view.setScaleY(scaleFactor); // Fade the page relative to its size. view.setAlpha(MIN_ALPHA + (scaleFactor - MIN_SCALE) / (1 - MIN_SCALE) * (1 - MIN_ALPHA)); } else { // (1,+Infinity] // This page is way off-screen to the right. view.setAlpha(0f); } } }
심도 페이지 변환기
이 페이지 변환기는 '심도' 페이지를 오른쪽으로 슬라이딩하는 애니메이션입니다. 심도 애니메이션은 페이지를 페이드아웃하고 선형적으로 축소합니다
깊이 애니메이션이 진행되는 동안 기본 애니메이션 (화면 슬라이드)이 계속 실행되므로 부정적인 X 번역으로 화면 슬라이드를 차단하세요. 예를 들면 다음과 같습니다.
Kotlin
view.translationX = -1 * view.width * position
자바
view.setTranslationX(-1 * view.getWidth() * position);
다음 예는 작동 중인 페이지 변환기:
Kotlin
private const val MIN_SCALE = 0.75f @RequiresApi(21) class DepthPageTransformer : ViewPager2.PageTransformer { override fun transformPage(view: View, position: Float) { view.apply { val pageWidth = width when { position < -1 -> { // [-Infinity,-1) // This page is way off-screen to the left. alpha = 0f } position <= 0 -> { // [-1,0] // Use the default slide transition when moving to the left page. alpha = 1f translationX = 0f translationZ = 0f scaleX = 1f scaleY = 1f } position <= 1 -> { // (0,1] // Fade the page out. alpha = 1 - position // Counteract the default slide transition. translationX = pageWidth * -position // Move it behind the left page. translationZ = -1f // Scale the page down (between MIN_SCALE and 1). val scaleFactor = (MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position))) scaleX = scaleFactor scaleY = scaleFactor } else -> { // (1,+Infinity] // This page is way off-screen to the right. alpha = 0f } } } } }
Java
@RequiresApi(21) public class DepthPageTransformer implements ViewPager2.PageTransformer { private static final float MIN_SCALE = 0.75f; public void transformPage(View view, float position) { int pageWidth = view.getWidth(); if (position < -1) { // [-Infinity,-1) // This page is way off-screen to the left. view.setAlpha(0f); } else if (position <= 0) { // [-1,0] // Use the default slide transition when moving to the left page. view.setAlpha(1f); view.setTranslationX(0f); view.setTranslationZ(0f); view.setScaleX(1f); view.setScaleY(1f); } else if (position <= 1) { // (0,1] // Fade the page out. view.setAlpha(1 - position); // Counteract the default slide transition. view.setTranslationX(pageWidth * -position); // Move it behind the left page view.setTranslationZ(-1f); // Scale the page down (between MIN_SCALE and 1). float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position)); view.setScaleX(scaleFactor); view.setScaleY(scaleFactor); } else { // (1,+Infinity] // This page is way off-screen to the right. view.setAlpha(0f); } } }
추가 리소스
ViewPager2
에 관해 자세히 알아보려면 다음 추가 리소스를 참조하세요.
샘플
- ViewPager2 샘플: GitHub를 참고하세요.
동영상
- 페이지 넘기기: ViewPager2로 이전 (Android Dev Summit '19)