اسلایدهای صفحه انتقال بین یک صفحه کامل به صفحه دیگر است و در رابطهای کاربری مانند جادوگران راهاندازی یا نمایش اسلاید رایج است. این درس به شما نشان میدهد که چگونه بااستفاده از ViewPager ارائهشده توسط کتابخانه پشتیبانی، اسلایدهای صفحهنمایش ایجاد کنید.
ViewPager شیء میتواند اسلایدهای صفحه را بهطور خودکار پویانمایی کند. در اینجا نحوه نمایش اسلاید صفحه که از یک صفحه محتوا به صفحه بعدی منتقل میشود نشان داده شده است:
ViewPager
بخشی از AndroidX است. برای اطلاعات بیشتر، به
استفاده از 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 android.support.v4.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 android.support.v4.app.Fragment; ... public class ScreenSlidePageFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { ViewGroup rootView = (ViewGroup) inflater.inflate( R.layout.fragment_screen_slide_page, container, false); return rootView; } }
افزودن ViewPager
اشیاء ViewPager دارای اشارههای تند کشیدن داخلی برای انتقال
در صفحهها هستند و بهطور پیشفرض پویانماییهای اسلاید صفحه را نمایش میدهند، بنابراین نیازی نیست
پویانمایی خودتان را ایجاد کنید. ViewPager از اشیای PagerAdapter بهعنوان منبعی برای نمایش صفحههای جدید استفاده میکند، بنابراین PagerAdapter از کلاس قطعهای که قبلاً ایجاد کردهاید استفاده خواهد کرد.
برای شروع، طرحبندیای ایجاد کنید که حاوی ViewPager باشد:
<!-- activity_screen_slide.xml --> <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" />
فعالیتی ایجاد کنید که کارهای زیر را انجام دهد:
- نمای محتوا را روی چیدمان با
ViewPagerتنظیم میکند. - کلاسی ایجاد میکند که کلاس انتزاعی
FragmentStatePagerAdapterرا گسترش میدهد و روشgetItem()را برای ارائه نمونههایScreenSlidePageFragmentبهعنوان صفحههای جدید پیادهسازی میکند. آداپتور صفحهبندی همچنین نیاز دارد که روشgetCount()را پیادهسازی کنید که تعداد صفحاتی را که آداپتور ایجاد میکند برمیگرداند (پنج صفحه در مثال). -
PagerAdapterرا بهViewPagerمتصل میکند.
کاتلین
import android.support.v4.app.Fragment import android.support.v4.app.FragmentManager ... /** * 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 mPager: ViewPager override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_screen_slide) // Instantiate a ViewPager and a PagerAdapter. mPager = findViewById(R.id.pager) // The pager adapter, which provides the pages to the view pager widget. val pagerAdapter = ScreenSlidePagerAdapter(supportFragmentManager) mPager.adapter = pagerAdapter } override fun onBackPressed() { if (mPager.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. mPager.currentItem = mPager.currentItem - 1 } } /** * A simple pager adapter that represents 5 ScreenSlidePageFragment objects, in * sequence. */ private inner class ScreenSlidePagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) { override fun getCount(): Int = NUM_PAGES override fun getItem(position: Int): Fragment = ScreenSlidePageFragment() } }
جاوا
import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; ... 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 ViewPager mPager; /** * The pager adapter, which provides the pages to the view pager widget. */ private PagerAdapter pagerAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_screen_slide); // Instantiate a ViewPager and a PagerAdapter. mPager = (ViewPager) findViewById(R.id.pager); pagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager()); mPager.setAdapter(pagerAdapter); } @Override public void onBackPressed() { if (mPager.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. mPager.setCurrentItem(mPager.getCurrentItem() - 1); } } /** * A simple pager adapter that represents 5 ScreenSlidePageFragment objects, in * sequence. */ private 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; } } }
سفارشیسازی کردن پویانمایی بااستفاده از PageTransformer
برای نمایش پویانماییای متفاوت از پویانمایی پیشفرض اسلاید صفحه، میانای
ViewPager.PageTransformer را پیادهسازی کنید و آن را به
نمای صفحهبندی ارائه دهید. این میانجی یک روش واحد، transformPage()، را نشان میدهد. در هر نقطه از انتقال صفحه، این روش یک بار برای هر صفحه قابل مشاهده (به طور کلی فقط یک صفحه قابل مشاهده وجود دارد) و برای صفحات مجاور درست خارج از صفحه فراخوانی می شود.
برای مثال، اگر صفحه سه نمایان باشد و کاربر بهسمت صفحه چهار بکشد،
transformPage()
برای صفحههای دو، سه، و چهار در هر مرحله از اشاره فراخوانی میشود.
در پیادهسازی transformPage()،
سپس میتوانید با تعیین اینکه کدام صفحهها باید براساس
موقعیت صفحه در صفحهنمایش تبدیل شوند، پویانماییهای اسلاید سفارشی ایجاد کنید، که از پارامتر position
روش transformPage() بهدست میآید.
پارامتر position نشان میدهد که صفحه موردنظر نسبتبه مرکز صفحهنمایش در کجا قرار دارد.
این یک دارایی پویا است که با پیمایش کاربر در صفحات تغییر میکند. وقتی صفحهای کل صفحهنمایش را پر میکند، مقدار موقعیت آن 0 است.
وقتی صفحهای درست در سمت راست صفحه کشیده میشود، مقدار موقعیت آن 1 است. اگر کاربر تا نیمه بین صفحه یک و دو پیمایش کند، صفحه یک موقعیت -۰٫۵ و صفحه دو موقعیت ۰٫۵ دارد. براساس موقعیت صفحهها در صفحه، میتوانید با تنظیم ویژگیهای صفحه با روشهایی مانند setAlpha()، setTranslationX()، یا setScaleY()، پویانماییهای اسلاید سفارشی ایجاد کنید.
وقتی پیادهسازی PageTransformer را دارید،
setPageTransformer() را با
پیادهسازیتان فراخوانی کنید تا پویانماییهای سفارشیتان اعمال شود. برای مثال، اگر
PageTransformer با نام
ZoomOutPageTransformer دارید، میتوانید پویانماییهای سفارشیتان را
بهاینصورت تنظیم کنید:
کاتلین
val mPager: ViewPager = findViewById(R.id.pager) ... mPager.setPageTransformer(true, ZoomOutPageTransformer())
جاوا
ViewPager mPager = (ViewPager) findViewById(R.id.pager); ... mPager.setPageTransformer(true, new ZoomOutPageTransformer());
برای مشاهده نمونهها و ویدیوهای PageTransformer، به بخشهای تبدیلکننده صفحه کوچکنمایی و تبدیلکننده صفحه عمق مراجعه کنید.
تبدیلکننده صفحه زومپس
این تبدیلکننده صفحه، هنگام پیمایش بین صفحههای مجاور، صفحهها را کوچک و محو میکند. وقتی صفحهای به مرکز نزدیکتر میشود، به اندازه عادی خود برمیگردد و محو میشود.
ZoomOutPageTransformer مثال
کاتلین
private const val MIN_SCALE = 0.85f private const val MIN_ALPHA = 0.5f class ZoomOutPageTransformer : ViewPager.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 ViewPager.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 class DepthPageTransformer : ViewPager.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 scaleX = 1f scaleY = 1f } position <= 1 -> { // (0,1] // Fade the page out. alpha = 1 - position // Counteract the default slide transition translationX = pageWidth * -position // 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 } } } } }
جاوا
public class DepthPageTransformer implements ViewPager.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.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); // 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); } } }