Android拖拽和嵌套滑动

2019-10-15  本文已影响0人  Hsicen

View.onDragListener(View)

使用

开启拖拽

val clipData = ClipData.newPlainText("name", "drag data")
ViewCompat.startDragAndDrop(view, clipData, View.DragShadowBuilder(it), "LocalState", 0)

//或者view.startDragAndDrop()
val clipData = ClipData.newPlainText("name", "drag data")
view.startDragAndDrop(clipData, View.DragShadowBuilder(it), "LocalState", 0)

拖拽监听

view.setOnDragListener(HDragListener)

//重写OnDragListener实现拖拽监听
inner class HDragListener : OnDragListener {
     override fun onDrag(v: View, event: DragEvent): Boolean {
           when (event.action) {
               DragEvent.ACTION_DRAG_STARTED ->{
                   //开始拖拽时回调
               }
               DragEvent.ACTION_DRAG_ENTERED ->{
                   //拖拽到View的边界内回调(可进行排序操作)
               }
               DragEvent.ACTION_DRAG_ENDED ->{
                   //结束拖拽时回调
               }
          }

          return true
    }
}

//或者重写View的onDragEvent()实现拖拽监听
override fun onDragEvent(event: DragEvent): Boolean {
  //当前界面中所有View都会回调这个方法
}

ViewDragHelper(ViewGroup)

使用:

自定义Callback实现ViewDragHelper.callback接口,监听拖拽回调

inner class HDragCallback : ViewDragHelper.Callback() {
 //记录下被托起的View的初始位置
 private var capturedLeft = 0
 private var capturedTop = 0

 /*** 返回true时View可以被拖起来*/
 override fun tryCaptureView(child: View, pointerId: Int): Boolean {
      return true
 }

 override fun clampViewPositionHorizontal(child: View, left: Int, dx: Int): Int {
      return left  //水平偏移
 }

 override fun clampViewPositionVertical(child: View, top: Int, dy: Int): Int {
      return top  //垂直偏移
 }

 /*** View被拖起时回调*/
 override fun onViewCaptured(capturedChild: View, activePointerId: Int) {
      capturedChild.elevation = elevation + 1
      capturedLeft = capturedChild.left
      capturedTop = capturedChild.top
 }

 /*** 拖拽状态改变时回调*/
 override fun onViewDragStateChanged(state: Int) {
      if (state == ViewDragHelper.STATE_IDLE) {
          val capturedView = mDragHelper.capturedView!!
          capturedView.elevation = capturedView.elevation - 1
      }
 }

 override fun onViewPositionChanged(changedView: View, left: Int, top: Int,dx: Int, dy: Int) {
      //位置改变时回调
 }

 /*** View被松开时回调*/
 override fun onViewReleased(releasedChild: View, xvel: Float, yvel: Float) {
      mDragHelper.settleCapturedViewAt(capturedLeft, capturedTop)
          //更新下一帧的绘制 和computeScroll结合
          postInvalidateOnAnimation()
  }
}

重写ViewGroup的onInterceptTouchEvent()和onTouchEvent()来接管触摸事件

private val mDragHelper by lazy {
  ViewDragHelper.create(this, HDragCallback())
}

override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
  return mDragHelper.shouldInterceptTouchEvent(ev)
}

override fun onTouchEvent(event: MotionEvent): Boolean {
  mDragHelper.processTouchEvent(event)
  return true
}

//和DragCallback的onViewReleased()相结合,循环绘制每一帧
override fun computeScroll() {
  if (mDragHelper.continueSettling(true)) {
          ViewCompat.postInvalidateOnAnimation(this)
  }
}

嵌套滑动

不同向嵌套

同向嵌套

上一篇 下一篇

猜你喜欢

热点阅读