自定义布局管理器滚动/动画

时间:2018-03-10 11:56:50

标签: android android-layout kotlin carousel

我正在尝试做什么。

使用 RecyclerView 创建一个简单的轮播。

问题

  1. 最初视图没有对齐到中心,视图没有得到我想要的样式。(即,完全可见的项目应该比其他项目大,当用手指滚动时它可以正常工作)
  2. 以编程方式滚动时,视图不会像使用手指滚动时那样获得捕捉效果。
  3. 例如,请参阅下面附带的 gif

    enter image description here

    问题

    1. 启动时如何使样式符合预期(即完全可见的项目更大)。
    2. 单击滚动到按钮时如何获取样式。 (它滚动到正确的位置,唯一的问题是没有按预期获得样式而且它不会对齐到中心)
    3. github

      上的完整代码

      以下是自定义 LayoutManager

      的代码
      open class CarouselLayoutManager(
          context: Context,
          orientation: Int,
          reverseLayout: Boolean
      ) : LinearLayoutManager(context, orientation, reverseLayout) {
      
      private val mShrinkAmount = 0.15f
      private val mShrinkDistance = 0.9f
      
      override fun onLayoutChildren(recycler: RecyclerView.Recycler?, state: RecyclerView.State?) {
          scrollVerticallyBy(0, recycler, state)
          super.onLayoutChildren(recycler, state)
      }
      
      override fun scrollHorizontallyBy(dx: Int, recycler: RecyclerView.Recycler?, state: RecyclerView.State?): Int {
          val orientation = orientation
          if (orientation == LinearLayoutManager.HORIZONTAL) {
              val scrolled = super.scrollHorizontallyBy(dx, recycler, state)
      
              val midpoint = width / 2f
              val d0 = 0f
              val d1 = mShrinkDistance * midpoint
              val s0 = 1f
              val s1 = 1f - mShrinkAmount
              for (i in 0 until childCount) {
                  val child = getChildAt(i)
                  val childMidpoint = (getDecoratedRight(child) + getDecoratedLeft(child)) / 2f
                  val d = Math.min(d1, Math.abs(midpoint - childMidpoint))
                  val scale = s0 + (s1 - s0) * (d - d0) / (d1 - d0)
                  child.scaleX = scale
                  child.scaleY = scale
              }
              return scrolled
          } else {
              return 0
          }
      }
      
      override fun scrollVerticallyBy(dy: Int, recycler: RecyclerView.Recycler?, state: RecyclerView.State?): Int {
          val orientation = orientation
          if (orientation == LinearLayoutManager.VERTICAL) {
              val scrolled = super.scrollVerticallyBy(dy, recycler, state)
              val midpoint = height / 2f
              val d0 = 0f
              val d1 = mShrinkDistance * midpoint
              val s0 = 1f
              val s1 = 1f - mShrinkAmount
              for (i in 0 until childCount) {
                  val child = getChildAt(i)
                  val childMidpoint = (getDecoratedBottom(child) + getDecoratedTop(child)) / 2f
                  val d = Math.min(d1, Math.abs(midpoint - childMidpoint))
                  val scale = s0 + (s1 - s0) * (d - d0) / (d1 - d0)
                  child.scaleX = scale
                  child.scaleY = scale
              }
              return scrolled
          } else {
              return 0
          }
      }
      

      }

2 个答案:

答案 0 :(得分:0)

最后,我通过使用这个库/示例

解决了这个问题
  1. DiscreteScrollView
  2. android-viewpager-transformers
  3. 以下是最终结果。

    有关完整代码,请参阅Carousel Demo

    enter image description here

答案 1 :(得分:0)

scrollVerticallyBy(0, recycler, state)方法调用onLayoutCompleted()