代码之家  ›  专栏  ›  技术社区  ›  Chad Schultz

如何查看recyclerview+pagersnaphelper

  •  9
  • Chad Schultz  · 技术社区  · 6 年前

    我在用水平仪 RecyclerView 具有 PagerSnapHelper 使它看起来像 ViewPager . 它在展示 CardViews .

    我的问题是,我如何才能让它显示一个小窥视的边缘,下一张和前一张卡?用户需要看一点这些卡,以便直观地理解他们需要水平刷卡,以便他们可以查看其他卡。

    我还将注意到,当前的卡总是需要居中,即使是第一张,也不会有前面的卡在左边偷看。另外,设计要求超出了我的控制;我需要偷看,我不能使用点指示器或其他任何东西。

    我需要一个 LinearSnapHelper 使卡片的宽度变小,但1)第一个项目将左对齐而不是居中,因为左侧没有卡片窥视,2)每张卡片的显示会根据手机的宽度变化多少。

    这看起来应该是一个普通而简单的任务,所以我希望我遗漏了一些显而易见的事情。

    1 回复  |  直到 6 年前
        1
  •  4
  •   Chad Schultz    6 年前

    经过反复试验,我找到了解决办法。幸运的是,事情并没有我想象的那么复杂,尽管没有我希望的那么干净。

    所以从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
            }
        }
    }
    

    当然,你会想改变的 40f 6f 为您的用例设置适当的值。

    如果您想知道,我有方向检查,因为在我的情况下,同一个适配器用于两个不同的recyclerview。一个是简单的垂直列表。另一个是水平的,功能类似于viewpager,这大大增加了复杂性。