簡體   English   中英

Android ViewPager2 setPageMargin 未解決

[英]Android ViewPager2 setPageMargin unresolved

我想使用View Pager2實現 Carousel 和左右頁面的預覽,如下所示:

在此處輸入圖片說明

最初我使用的是支持的視圖 pager1。 現在我認為它被刪除了

    viewPagerhost.setPageMargin(20);

知道我們如何使用 View Pager 2 實現這一點

MarginPageTransformer無法滿足您的需求。

您必須使用自定義setPageTrarnsformer


第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">

現在我們需要在Version 1.0.0-alpha05使用setPageTransformer()

新功能

  • ItemDecorator引入了與 RecyclerView 一致的行為。
  • 引入MarginPageTransformer以提供在頁面之間(頁面插圖之外)創建空間的能力。
  • 引入CompositePageTransformer以提供組合多個 PageTransformer 的能力。

示例代碼

myViewPager2.setPageTransformer(new MarginPageTransformer(1500));

如果您想使用 View Pager2 實現 Carousel,請查看我之前的回答

ViewPager2目前(版本1.0.0), ViewPager2還沒有方法setPageMargin 但是,您可以使用RecyclerView.ItemDecorationPageTransformer創建所需的輪播。

結果

在此處輸入圖片說明

代碼

在您的活動/片段中,設置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上使用此布局時所需的頁邊距。

PageTransformer示例

谷歌增加了對ViewPager2一個指南,有2個PageTransformer實現,你可以作為一個啟發使用: https://developer.android.com/training/animation/screen-slide-2

ViewPager2有用的鏈接

我使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM