MarginPageTransformer
cannot help your need.
You must use custom setPageTrarnsformer .
Here is my Extension Method for this.
you can check detail in this article Medium article
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
}
}
}
set pageMarginPx and offsetPx with your use case.
<resources>
<dimen name="pageMargin">20dp</dimen>
<dimen name="pagerOffset">30dp</dimen>
<dimen name="pageMarginAndoffset">50dp</dimen>
</resources>
set your side margin of layout item in your xml.
like this
<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">
Now we need to use setPageTransformer()
in Version 1.0.0-alpha05
New features
ItemDecorator
introduced with a behaviour consistent with RecyclerView. MarginPageTransformer
introduced to provide an ability to create space between pages (outside of page inset).CompositePageTransformer
introduced to provide an ability to combine multiple PageTransformers.SAMPLE CODE
myViewPager2.setPageTransformer(new MarginPageTransformer(1500));
Check out my previous answer if you want to implement Carousel using View Pager2
ViewPager2
doesn't have the method setPageMargin
as of now (version 1.0.0). However you can create the carousel you want with a RecyclerView.ItemDecoration
and a PageTransformer
.
In your Activity/Fragment, setup the 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)
Add the HorizontalMarginItemDecoration
, which is a trivial 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
}
}
Add the dimensions that control how much of the previous/next item is visible, and current item horizontal margin:
<dimen name="viewpager_next_item_visible">26dp</dimen>
<dimen name="viewpager_current_item_horizontal_margin">42dp</dimen>
ItemDecoration
vs adding margins to the item's layout If you look at other answers, you'll see that you can achieve the same result without the ItemDecoration
, simply by adding left and right margins directly to your item's layout:
<androidx.cardview.widget.CardView
android:layout_marginLeft="@dimen/pageMarginAndOffset"
android:layout_marginRight="@dimen/pageMarginAndOffset">
While the result is the same, using an ItemDecoration
allows you to re-use the same layout in other places without having to deal with this margins that are needed only when using this layout on a ViewPager.
Google has added a guide on ViewPager2 that has 2 PageTransformer
implementations that you can use as an inspiration: https://developer.android.com/training/animation/screen-slide-2
I used MJ Studio's approach to create my custom PageTransformer
that also changes the page margin as follows:
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."
)
}
}
That way you can just call:
viewPager.setPageTransformer(OffsetPageTransformer(offsetPx, pageMarginPx))
you can use this code
viewPager.setPageTransformer(new MarginPageTransformer(margin as PX));
but if you want to use DP you can use the below function for convert PX to DP
private int pxToDp(int px) {
return (int) (px / Resources.getSystem().getDisplayMetrics().density);
}
MarginPageTransformer
helps to define spaces between pages.
offscreenPageLimit
let you define how many pages should be rendered offscreen.
Sample of the code:
viewPager2.offscreenPageLimit = 3
viewPager2.setPageTransformer(MarginPageTransformer({MARGIN AS PX}));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.