如何查看RecyclerView + PagerSnapHelper

时间:2018-06-16 03:23:50

标签: android android-layout android-recyclerview

我使用横向RecyclerViewPagerSnapHelper使其看起来像ViewPager。它显示CardViews

我的问题是,如何让它显示下一张和上一张卡的边缘?用户需要查看一些这样的卡片,以便他们直观地理解他们需要水平滑动才能查看其他卡片。

我还会注意到,当前的卡片总是需要居中,即使对于第一张卡片也是如此,左边没有先前的卡片偷看。此外,设计要求不受我的控制;我需要偷看,我不能使用点指示器或其他任何东西。

我可以使用LinearSnapHelper并使卡片的宽度变小,但是1)第一项将左对齐而不是居中,因为左侧没有卡片偷看而且2)如何每张卡片显示的大部分内容都会根据手机的宽度而有所不同。

这似乎应该是一项普通而简单的任务,所以我希望我找不到明显的事情来实现它。

1 个答案:

答案 0 :(得分:4)

经过反复试验,我找到了解决方案。幸运的是,它虽然没有我希望的那么干净,却没有我想的那么复杂。

所以从RecyclerView及其适配器开始,使用水平方向的LinearLayoutManager,添加PagerSnapHelper,依此类推...然后解决这个问题中的特定问题,我对适配器做了一些调整:

private var orientation: Int? = null

override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
    super.onAttachedToRecyclerView(recyclerView)
    orientation = (recyclerView.layoutManager as LinearLayoutManager).orientation
}

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    // Kludge to adjust margins for horizontal, ViewPager style RecyclerView
    if (orientation != LinearLayout.VERTICAL) {
        holder.itemView.layoutParams = (holder.itemView.layoutParams as RecyclerView.LayoutParams).apply {
            val displayMetrics = DisplayMetrics()
            baseActivity.windowManager.defaultDisplay.getMetrics(displayMetrics)
            // To show the edge of the next/previous card on the screen, we'll adjust the width of our MATCH_PARENT card to make
            // it just slightly smaller than the screen. That way, no matter the size of the screen, the card will fill most of
            // it and show a hint of the next cards.
            val widthSubtraction = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 40f, displayMetrics).toInt()
            width = displayMetrics.widthPixels - widthSubtraction
            // We always want the spot card centered. But the RecyclerView will left-align the first card and right-align the
            // last card, since there's no card peeking on that size. We'll adjust the margins in those two places to pad it out
            // so those cards appear centered.
            // Theoretically we SHOULD be able to just use half of the amount we shrank the card by, but for some reason that's
            // not quite right, so I'm adding a fudge factor developed via trial and error to make it look better.
            val fudgeFactor = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 6f, displayMetrics).toInt()
            val endAdjustment = (widthSubtraction / 2) - fudgeFactor
            marginStart = if (position == 0) endAdjustment else 0
            marginEnd = if (position == (itemCount - 1)) endAdjustment else 0
        }
    }
}

当然,您需要将40f6f更改为适合您的用例的值。

如果您想知道,我进行了方向检查,因为就我而言,同一个适配器用于两个不同的RecyclerViews。一个是简单的垂直列表。另一个是水平的,功能类似于ViewPager,大大增加了复杂性。