[英]Android ViewPager2 setPageMargin unresolved
MarginPageTransformer
无法满足您的需求。
您必须使用自定义setPageTrarnsformer 。
这是我的扩展方法。
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
}
}
}
根据您的用例设置 pageMarginPx 和 offsetPx。
<resources>
<dimen name="pageMargin">20dp</dimen>
<dimen name="pagerOffset">30dp</dimen>
<dimen name="pageMarginAndoffset">50dp</dimen>
</resources>
在 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">
现在我们需要在Version 1.0.0-alpha05
使用setPageTransformer()
新功能
ItemDecorator
引入了与 RecyclerView 一致的行为。MarginPageTransformer
以提供在页面之间(页面插图之外)创建空间的能力。CompositePageTransformer
以提供组合多个 PageTransformer 的能力。示例代码
myViewPager2.setPageTransformer(new MarginPageTransformer(1500));
ViewPager2
目前(版本1.0.0), ViewPager2
还没有方法setPageMargin
。 但是,您可以使用RecyclerView.ItemDecoration
和PageTransformer
创建所需的轮播。
在您的活动/片段中,设置ViewPager2:
// MyRecyclerViewAdapter is an standard RecyclerView.Adapter :)
viewPager2.adapter = MyRecyclerViewAdapter()
// You need to retain one page on each side so that the next and previous items are visible
viewPager2.offscreenPageLimit = 1
// Add a PageTransformer that translates the next and previous items horizontally
// towards the center of the screen, which makes them visible
val nextItemVisiblePx = resources.getDimension(R.dimen.viewpager_next_item_visible)
val currentItemHorizontalMarginPx = resources.getDimension(R.dimen.viewpager_current_item_horizontal_margin)
val pageTranslationX = nextItemVisiblePx + currentItemHorizontalMarginPx
val pageTransformer = ViewPager2.PageTransformer { page: View, position: Float ->
page.translationX = -pageTranslationX * position
// Next line scales the item's height. You can remove it if you don't want this effect
page.scaleY = 1 - (0.25f * abs(position))
// If you want a fading effect uncomment the next line:
// page.alpha = 0.25f + (1 - abs(position))
}
viewPager2.setPageTransformer(pageTransformer)
// The ItemDecoration gives the current (centered) item horizontal margin so that
// it doesn't occupy the whole screen width. Without it the items overlap
val itemDecoration = HorizontalMarginItemDecoration(
context,
R.dimen.viewpager_current_item_horizontal_margin
)
viewPager2.addItemDecoration(itemDecoration)
添加HorizontalMarginItemDecoration
,这是一个琐碎的ItemDecoration
:
/**
* Adds margin to the left and right sides of the RecyclerView item.
* Adapted from https://stackoverflow.com/a/27664023/4034572
* @param horizontalMarginInDp the margin resource, in dp.
*/
class HorizontalMarginItemDecoration(context: Context, @DimenRes horizontalMarginInDp: Int) :
RecyclerView.ItemDecoration() {
private val horizontalMarginInPx: Int =
context.resources.getDimension(horizontalMarginInDp).toInt()
override fun getItemOffsets(
outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State
) {
outRect.right = horizontalMarginInPx
outRect.left = horizontalMarginInPx
}
}
添加尺寸以控制可见的上一个/下一个项目以及当前项目的水平边距:
<dimen name="viewpager_next_item_visible">26dp</dimen>
<dimen name="viewpager_current_item_horizontal_margin">42dp</dimen>
ItemDecoration
与在项目布局中增加边距 如果您查看其他答案,您会发现无需ItemDecoration
就可以达到相同的结果,只需将左右边距直接添加到项目的布局即可:
<androidx.cardview.widget.CardView
android:layout_marginLeft="@dimen/pageMarginAndOffset"
android:layout_marginRight="@dimen/pageMarginAndOffset">
虽然结果相同,但使用ItemDecoration
可以使您在其他地方重用相同的布局,而不必处理仅在ViewPager上使用此布局时所需的页边距。
谷歌增加了对ViewPager2一个指南,有2个PageTransformer
实现,你可以作为一个启发使用: https://developer.android.com/training/animation/screen-slide-2
我使用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))
你可以使用这个代码
viewPager.setPageTransformer(new MarginPageTransformer(margin as PX));
但是如果你想使用 DP 你可以使用下面的函数将 PX 转换为 DP
private int pxToDp(int px) {
return (int) (px / Resources.getSystem().getDisplayMetrics().density);
}
MarginPageTransformer
有助于定义页面之间的空间。
offscreenPageLimit
让您定义应在屏幕外呈现的页面数。
代码示例:
viewPager2.offscreenPageLimit = 3
viewPager2.setPageTransformer(MarginPageTransformer({MARGIN AS PX}));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.