text: package com.engineer.imitate.ui.widget.more
  
  import android.annotation.SuppressLint
  import android.content.Context
  import android.graphics.Color
  import android.util.AttributeSet
  import android.util.Log
  import android.view.View
  import android.view.animation.AccelerateInterpolator
  import android.view.animation.Animation
  import android.view.animation.Transformation
  import android.widget.LinearLayout
  import androidx.core.view.NestedScrollingParent
  import androidx.core.view.NestedScrollingParentHelper
  import androidx.core.view.ViewCompat
  import androidx.recyclerview.widget.RecyclerView
  import com.engineer.imitate.util.dp
  
  class DZStickyNavLayouts(
      context: Context,
      attrs: AttributeSet?
  ) : LinearLayout(context, attrs), NestedScrollingParent {
      private val mParentHelper: NestedScrollingParentHelper
      private val mHeaderView: View
      private val mFooterView: AnimatorView
      private var mChildView: RecyclerView? = null
  
      // 解决多点触控问题
      private var isRunAnim = false
  
      interface OnStartActivityListener {
          fun onStart()
      }
  
      private var mLinster: OnStartActivityListener? = null
      fun setOnStartActivity(l: OnStartActivityListener?) {
          mLinster = l
      }
  
      override fun onFinishInflate() {
          Log.d(TAG, "onFinishInflate() called");
          super.onFinishInflate()
          orientation = HORIZONTAL
          Log.d(TAG, ": $childCount")
          Log.d(TAG, ": $maxWidth")
          if (getChildAt(0) is RecyclerView) {
              mChildView = getChildAt(0) as RecyclerView
              val layoutParams = LayoutParams(
                  maxWidth,
                  LayoutParams.WRAP_CONTENT
              )
              addView(mHeaderView, 0, layoutParams)
              addView(mFooterView, childCount, layoutParams)
              // 左移
              scrollBy(maxWidth, 0)
              mChildView!!.setOnTouchListener { v, event -> // 保证动画状态中 子view不能滑动
                  isRunAnim
              }
          }
      }
  
      override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
  //        Log.d(TAG, "onMeasure() called")
          super.onMeasure(widthMeasureSpec, heightMeasureSpec)
          if (mChildView != null) {
              val params = mChildView!!.layoutParams
              params.width = measuredWidth
          }
      }
  
  
      /**
       * @param dx       水平滑动距离
       * @param dy       垂直滑动距离
       * @param consumed 父类消耗掉的距离
       */
      @SuppressLint("LogNotTimber")
      override fun onNestedPreScroll(
          target: View,
          dx: Int,
          dy: Int,
          consumed: IntArray
      ) {
          parent.requestDisallowInterceptTouchEvent(true)
          Log.d(TAG, "onNestedPreScroll() called scrollX = $scrollX")
          // dx>0 往左滑动 dx<0往右滑动
          Log.d(TAG, "dx=" + dx + ",getScrollX=" + scrollX +
                  ",canScrollHorizontally=" + !target.canScrollHorizontally(1))
          val hiddenLeft =
              dx > 0 && scrollX < maxWidth && !target.canScrollHorizontally(-1)
          val showLeft =
              dx < 0 && !target.canScrollHorizontally( -1)
          val hiddenRight =
              dx < 0 && scrollX > maxWidth && !target.canScrollHorizontally(1)
          val showRight =
              dx > 0 && !target.canScrollHorizontally(1)
  
          Log.d(TAG,"showRight = $showRight, hideRight = $hiddenRight")
  
          if (hiddenLeft || hiddenRight || showRight) {
              scrollBy(dx / DRAG, 0)
              consumed[0] = dx
          }
          if (hiddenRight || showRight) {
              mFooterView.setRefresh(dx / DRAG)
          }
  
          // 限制错位问题
          if (dx > 0 && scrollX > maxWidth  && !target.canScrollHorizontally(-1)) {
              scrollTo(maxWidth, 0)
          }
  
          if (dx < 0 && scrollX < maxWidth && !target.canScrollHorizontally(1)) {
              scrollTo(maxWidth, 0)
          }
      }
  
      /**
       * 必须要复写 onStartNestedScroll后调用
       */
      override fun onNestedScrollAccepted(
          child: View,
          target: View,
          axes: Int
      ) {
          Log.d(TAG, "onNestedScrollAccepted() called scrollX = $scrollX")
          mParentHelper.onNestedScrollAccepted(child, target, axes)
      }
  
      /**
       * 返回true代表处理本次事件
       * 在执行动画时间里不能处理本次事件
       */
      override fun onStartNestedScroll(
          child: View,
          target: View,
          nestedScrollAxes: Int
      ): Boolean {
          Log.d(TAG, "onStartNestedScroll() called scrollX = $scrollX")
          return target is RecyclerView && !isRunAnim
      }
  
      /**
       * 复位初始位置
       * scrollTo 移动到指定坐标
       * scrollBy 在原有坐标上面移动
       */
      override fun onStopNestedScroll(target: View) {
          mParentHelper.onStopNestedScroll(target)
          Log.d(TAG, "onStopNestedScroll() called scrollX = " + scrollX)
          // 如果不在RecyclerView滑动范围内
          if (maxWidth != scrollX) {
              startAnimation(ProgressAnimation())
          }
          if (scrollX > maxWidth + maxWidth / 2 && mLinster != null) {
              mLinster!!.onStart()
          }
      }
  
      /**
       * 回弹动画
       */
      private inner class ProgressAnimation : Animation() {
  
          override fun applyTransformation(
              interpolatedTime: Float,
              t: Transformation
          ) {
              scrollBy(
                  ((maxWidth - scrollX) * interpolatedTime).toInt(),
                  0
              )
              if (interpolatedTime == 1f) {
                  isRunAnim = false
                  mFooterView.setRelease()
              }
          }
  
          override fun initialize(
              width: Int,
              height: Int,
              parentWidth: Int,
              parentHeight: Int
          ) {
              super.initialize(width, height, parentWidth, parentHeight)
              duration = 300
              interpolator = AccelerateInterpolator()
          }
  
          init {
              isRunAnim = true
          }
      }
  
      override fun onNestedScroll(
          target: View,
          dxConsumed: Int,
          dyConsumed: Int,
          dxUnconsumed: Int,
          dyUnconsumed: Int
      ) {
      }
  
  
      override fun onNestedFling(
          target: View,
          velocityX: Float,
          velocityY: Float,
          consumed: Boolean
      ): Boolean {
          return false
      }
  
      /**
       * 子view是否可以有惯性 解决右滑时快速左滑显示错位问题
       *
       * @return true不可以  false可以
       */
      override fun onNestedPreFling(
          target: View,
          velocityX: Float,
          velocityY: Float
      ): Boolean {
          // 当RecyclerView在界面之内交给它自己惯性滑动
          return scrollX != maxWidth
      }
  
      override fun getNestedScrollAxes(): Int {
          return 0
      }
  
      /**
       * 限制滑动 移动x轴不能超出最大范围
       */
      override fun scrollTo(x: Int, y: Int) {
          var x = x
          if (x < 0) {
              x = 0
          } else if (x > maxWidth * 2) {
              x = maxWidth * 2
          }
          super.scrollTo(x, y)
      }
  
      private fun dp2Px(context: Context, dp: Float): Int {
          val scale = context.resources.displayMetrics.density
          return (dp * scale + 0.5f).toInt()
      }
  
      companion object {
          @JvmField
          var maxWidth = 0
          private const val DRAG = 2
          val TAG = "tag"
      }
  
      init {
          mHeaderView = View(context)
          mHeaderView.setBackgroundColor(-0x1)
          mFooterView = AnimatorView(context)
          mFooterView.setBackgroundColor(Color.TRANSPARENT)
          maxWidth = 60.dp
          mParentHelper = NestedScrollingParentHelper(this)
      }
  }