Android ViewPager2 setPageMargin 未解决

问题描述 投票:0回答:6

我想使用

View Pager2
实现轮播,并预览左右页面,如下所示:

最初我使用的是支持的view pager1。现在我认为它被删除了

    viewPagerhost.setPageMargin(20);

知道我们如何使用 View Pager 2 来实现这一点吗

android carousel android-viewpager2
6个回答
41
投票

MarginPageTransformer
无法满足您的需求。

您必须使用自定义 setPageTransformer


步骤1

这是我的扩展方法。

详细内容可以查看这篇文章 中篇文章

fun ViewPager2.setShowSideItems(pageMarginPx : Int, offsetPx : Int) {

    clipToPadding = false
    clipChildren = false
    offscreenPageLimit = 3

    setPageTransformer { page, position ->

        val offset = position * -(2 * offsetPx + pageMarginPx)
        if (this.orientation == ViewPager2.ORIENTATION_HORIZONTAL) {
            if (ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL) {
                page.translationX = -offset
            } else {
                page.translationX = offset
            }
        } else {
            page.translationY = offset
        }
    }

}

步骤2

根据您的用例设置 pageMarginPx 和 offsetPx。

<resources>
    <dimen name="pageMargin">20dp</dimen>
    <dimen name="pagerOffset">30dp</dimen>
    <dimen name="pageMarginAndoffset">50dp</dimen>
</resources>

步骤3

在 xml 中设置布局项目的侧边距。

像这样

    <androidx.cardview.widget.CardView
            app:cardCornerRadius="12dp"

            android:layout_marginTop="16dp"
            android:layout_marginBottom="16dp"

            android:layout_marginLeft="@dimen/pageMarginAndoffset"
            android:layout_marginRight="@dimen/pageMarginAndoffset"

            android:layout_width="match_parent"
            android:layout_height="match_parent">

21
投票

现在我们需要在

setPageTransformer()
中使用
Version 1.0.0-alpha05

新功能

  • ItemDecorator
    引入了与 RecyclerView 一致的行为。
  • MarginPageTransformer
    引入是为了提供在页面之间(页面插入之外)创建空间的能力。
  • CompositePageTransformer
    的引入提供了组合多个PageTransformers的能力。

示例代码

myViewPager2.setPageTransformer(new MarginPageTransformer(1500));

如果您想使用 View Pager2 实现轮播,请查看 我之前的答案


4
投票

我使用 MJ Studio 的方法来创建我的自定义

PageTransformer
,它还更改了页边距,如下所示:

class OffsetPageTransformer(
    @Px private val offsetPx: Int,
    @Px private val pageMarginPx: Int
) : ViewPager2.PageTransformer {

    override fun transformPage(page: View, position: Float) {
        val viewPager = requireViewPager(page)
        val offset = position * -(2 * offsetPx + pageMarginPx)
        val totalMargin = offsetPx + pageMarginPx

        if (viewPager.orientation == ViewPager2.ORIENTATION_HORIZONTAL) {
            page.updateLayoutParams<ViewGroup.MarginLayoutParams> {
                marginStart = totalMargin
                marginEnd = totalMargin
            }

            page.translationX = if (ViewCompat.getLayoutDirection(viewPager) == ViewCompat.LAYOUT_DIRECTION_RTL) {
                -offset
            } else {
                offset
            }
        } else {
            page.updateLayoutParams<ViewGroup.MarginLayoutParams> {
                topMargin = totalMargin
                bottomMargin = totalMargin
            }

            page.translationY = offset
        }
    }

    private fun requireViewPager(page: View): ViewPager2 {
        val parent = page.parent
        val parentParent = parent.parent
        if (parent is RecyclerView && parentParent is ViewPager2) {
            return parentParent
        }
        throw IllegalStateException(
            "Expected the page view to be managed by a ViewPager2 instance."
        )
    }
}

这样您就可以拨打:

viewPager.setPageTransformer(OffsetPageTransformer(offsetPx, pageMarginPx))

0
投票

您可以使用此代码

   viewPager.setPageTransformer(new MarginPageTransformer(margin as PX));

但是如果你想使用DP,你可以使用下面的函数将PX转换为DP

 private  int pxToDp(int px) {
    return (int) (px / Resources.getSystem().getDisplayMetrics().density);
}

0
投票

MarginPageTransformer
有助于定义页面之间的空间。

offscreenPageLimit
让您定义应在屏幕外呈现多少页面。

代码示例:

viewPager2.offscreenPageLimit = 3
viewPager2.setPageTransformer(MarginPageTransformer({MARGIN AS PX}));

0
投票

如果有人想要实现第一个项目仅在右侧有空格而最后一个项目仅在左侧有空格的情况,请添加到上述答案。

将此代码应用到您的viewpager2

viewPagerPhotos.apply {
    adapter = photosAdapter

    clipToPadding = false
    clipChildren = false
    offscreenPageLimit = 3

    val pageMargin = 16.dpToPx(this@MaintenanceCenterDetailsActivity)
    val offset = 24.dpToPx(this@MaintenanceCenterDetailsActivity)
    setPageTransformer { page, position ->
        val pageOffset = position * -(2 * offset + pageMargin)
        if (viewPagerPhotos.orientation == ViewPager2.ORIENTATION_HORIZONTAL) {
            if (ViewCompat.getLayoutDirection(viewPagerPhotos) == ViewCompat.LAYOUT_DIRECTION_RTL) {
                page.translationX = -pageOffset
            } else {
                page.translationX = pageOffset
            }
        } else {
            page.translationY = pageOffset
        }
    }
}

然后在你的视图持有者中你需要执行以下操作

fun bind(photoUrl: String) {
    with(binding.root) {
        if (itemCount > 1) {
            updateLayoutParams<ViewGroup.MarginLayoutParams> {
                when (layoutPosition) {
                    0 -> {
                        marginStart = 0
                        marginEnd = marginValue
                    }
                    itemCount - 1 -> {
                        marginStart = marginValue
                        marginEnd = 0
                    }
                    else -> {
                        marginStart = marginValue
                        marginEnd = marginValue
                    }
                }
            }
        }

        load(photoUrl) {
            crossfade(true)
        }
    }
}

这是将 dp 转换为 px 的扩展函数

fun Int.dpToPx(context: Context): Int {
    val resources = context.resources
    val scale = resources.displayMetrics.density
    return (this * scale).toInt()
}
© www.soinside.com 2019 - 2024. All rights reserved.