اسلایدهای صفحه انتقال از یک صفحه کامل به صفحه دیگر هستند و در میاناهای کاربر مانند دستیارهای راهاندازی و نمایش اسلاید رایج هستند. این موضوع به شما نشان میدهد که چگونه با شیء
ViewPager2
اسلاید صفحه انجام دهید. ViewPager2 شیء میتواند اسلایدهای صفحه را بهطور خودکار پویانمایی کند. در اینجا نمونهای از اسلاید صفحه آورده شده است که از یک صفحه محتوا به صفحه بعدی منتقل میشود:
اگر میخواهید جلو بروید و یک نمونه کامل درحال کار را ببینید، این برنامه نمونه را در GitHub مشاهده کنید.
برای استفاده از 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()
ایجاد کردهاید برگرداند. سپس میتوانید هر زمان که به صفحه جدیدی برای نمایش به کاربر نیاز داشتید، نمونههایی از این قطعه را در فعالیت والد ایجاد کنید:
کاتلین
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()را برای آداپتور ورقزن پیادهسازی کنید، که تعداد صفحاتی را که آداپتور ایجاد میکند برمیگرداند. در این مثال، پنج مورد وجود دارد. FragmentStateAdapterرا به اشیایViewPager2متصل میکند.
کاتلین
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().
در هر نقطه از انتقال صفحهنمایش، این روش یکبار برای هر صفحه قابلمشاهده فراخوانی میشود—معمولاً
فقط یک صفحه قابلمشاهده وجود دارد—و برای صفحههای مجاور خارج از صفحهنمایش. برای مثال، اگر صفحه سه نمایان باشد و کاربر بهسمت صفحه چهار بکشد، transformPage() در هر مرحله از اشاره برای صفحههای دو، سه، و چهار فراخوانی میشود.
سپس در پیادهسازی transformPage()، میتوانید با تعیین اینکه کدام صفحهها باید براساس موقعیت صفحه در صفحهنمایش تبدیل شوند، پویانماییهای سفارشی برای اسلاید ایجاد کنید. موقعیت صفحه را از پارامتر position
روش transformPage() دریافت کنید.
پارامتر position نشان میدهد که صفحه موردنظر نسبت به مرکز صفحهنمایش در کجا قرار دارد. این پارامتر یک ویژگی پویا است که با پیمایش کاربر در مجموعهای از صفحهها تغییر میکند. وقتی صفحهای کل صفحهنمایش را پر میکند، مقدار موقعیت آن 0 است. وقتی صفحهای
از سمت راست صفحه خارج میشود، مقدار موقعیت آن 1 است. اگر کاربر تا نیمه بین صفحههای یک و دو پیمایش کند، صفحه یک موقعیت -0.5 و صفحه دو موقعیت 0.5 را دارد. براساس موقعیت صفحهها در صفحه، میتوانید
با تنظیم ویژگیهای صفحه با روشهایی مثل
setAlpha()،
setTranslationX()،
یا
setScaleY()
پویانماییهای اسلاید سفارشی ایجاد کنید.
وقتی پیادهسازی
PageTransformer دارید،
setPageTransformer()
را با پیادهسازیتان فراخوانی کنید تا پویانماییهای سفارشیتان اعمال شود. برای مثال، اگر
PageTransformer با نام ZoomOutPageTransformer دارید، میتوانید
پویانماییهای سفارشیتان را به این صورت تنظیم کنید:
کاتلین
val viewPager: ViewPager2 = findViewById(R.id.pager) ... viewPager.setPageTransformer(ZoomOutPageTransformer())
جاوا
ViewPager2 viewPager = findViewById(R.id.pager); ... viewPager.setPageTransformer(new ZoomOutPageTransformer());
برای نمونههایی از
PageTransformer، بخشهای مبدل صفحه زومپس و
مبدل صفحه عمق را ببینید.
تبدیلکننده صفحه زومپَس
این تبدیلکننده صفحه، صفحهها را هنگام پیمایش بین صفحههای مجاور کوچک و محو میکند. وقتی صفحهای به مرکز نزدیکتر میشود، به اندازه عادی خود برمیگردد و ظاهر میشود.
ZoomOutPageTransformer مثال.
کاتلین
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); } } }
تبدیلکننده صفحه عمق
این تبدیلکننده صفحه از پویانمایی پیشفرض اسلاید برای لغزاندن صفحهها به چپ استفاده میکند، درحالیکه از پویانمایی «عمق» برای لغزاندن صفحهها به راست استفاده میکند. این پویانمایی عمق، صفحه را محو میکند و آن را بهصورت خطی کوچک میکند.
DepthPageTransformer مثال.
درطول پویانمایی عمق، پویانمایی پیشفرض (لغزاندن صفحه) همچنان انجام میشود، بنابراین باید با ترجمه X منفی، لغزاندن صفحه را خنثی کنید. برای مثال:
کاتلین
view.translationX = -1 * view.width * position
جاوا
view.setTranslationX(-1 * view.getWidth() * position);
مثال زیر نشان میدهد که چگونه میتوان پویانمایی پیشفرض لغزش صفحه را در یک تبدیلکننده صفحه فعال خنثی کرد:
کاتلین
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 } } } } }
جاوا
@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.
ویدیوها
- Turning the Page: Migrating to ViewPager2 (Android Dev Summit '19)