[英]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.