اسلایدهای صفحه انتقال از یک صفحه کامل به صفحه دیگر هستند و در رابطهای کاربری مانند جادوگرهای راهاندازی و نمایش اسلاید رایج هستند. این موضوع به شما نشان می دهد که چگونه اسلایدهای صفحه را با یک شی 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
، بخشهای ترانسفورماتور صفحه بزرگنمایی و ترانسفورماتور صفحه عمق را ببینید.
ترانسفورماتور صفحه بزرگنمایی
این ترانسفورماتور صفحه هنگام پیمایش بین صفحات مجاور صفحات را کوچک و محو می کند. همانطور که یک صفحه به مرکز نزدیکتر می شود، به اندازه طبیعی خود باز می گردد و محو می شود.
کاتلین
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 منفی با اسلاید صفحه مقابله کنید. به عنوان مثال:
کاتلین
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.
ویدیوها
- چرخاندن صفحه: مهاجرت به ViewPager2 (Android Dev Summit '19)