1+ package com.goyourfly.multiple.adapter.viewholder
2+
3+ import android.content.Context
4+ import android.support.v4.view.MotionEventCompat
5+ import android.util.Log
6+ import android.view.MotionEvent
7+ import android.view.View
8+ import android.widget.FrameLayout
9+ import com.goyourfly.multiple.adapter.MultipleAdapter
10+ import com.goyourfly.multiple.adapter.ViewState
11+
12+ /* *
13+ * Created by gaoyufei on 2017/7/20.
14+ */
15+
16+ class InterceptFrameLayout (context : Context , val adapter : MultipleAdapter , child : View ) : FrameLayout(context) {
17+ val CLICK_ACTION_THRESHHOLD = 20
18+ val CLICK_LONG_TIME = 500L
19+
20+ var startX = 0F
21+ var startY = 0F
22+ var moveX = 0F
23+ var moveY = 0F
24+ var downTime = 0L
25+ var isTouching = false
26+ var isLongClick = false
27+ var touchDownTime = 0L
28+
29+ private var onLongClicked: (() -> Unit )? = null
30+ private var onClick: (() -> Unit )? = null
31+
32+ val run = Runnable {
33+ if (isTouching && ! isLongClick && isAClick()) {
34+ // 制作一个假的事件
35+ val event = MotionEvent .obtain(
36+ downTime,
37+ System .currentTimeMillis(),
38+ MotionEvent .ACTION_MOVE ,
39+ moveX,
40+ moveY,
41+ 0 )
42+ isLongClick = true
43+ onTouchEvent(event)
44+ }
45+ }
46+
47+ init {
48+ val childParams = child.layoutParams
49+ val params =
50+ if (childParams != null )
51+ LayoutParams (childParams)
52+ else
53+ LayoutParams (LayoutParams .MATCH_PARENT , LayoutParams .MATCH_PARENT )
54+ layoutParams = params
55+ addView(child)
56+ }
57+
58+ override fun onInterceptTouchEvent (ev : MotionEvent ): Boolean {
59+ Log .d(" ..." , " onIntercept:$ev " )
60+ val action = MotionEventCompat .getActionMasked(ev)
61+ when (action) {
62+ MotionEvent .ACTION_DOWN -> {
63+ isLongClick = false
64+ isTouching = true
65+ startX = ev.x
66+ startY = ev.y
67+ moveX = ev.x
68+ moveY = ev.y
69+ downTime = System .currentTimeMillis()
70+ handler.postDelayed(run, CLICK_LONG_TIME )
71+ }
72+ MotionEvent .ACTION_MOVE -> {
73+ moveX = ev.x
74+ moveY = ev.y
75+ if (isInterceptLong() && isAClick()) {
76+ isLongClick = true
77+ }
78+ }
79+ MotionEvent .ACTION_UP , MotionEvent .ACTION_CANCEL -> {
80+ isTouching = false
81+ handler.removeCallbacks(run)
82+ }
83+ }
84+ return isLongClick || adapter.showState == ViewState .SELECT
85+ }
86+
87+
88+ override fun onTouchEvent (ev : MotionEvent ): Boolean {
89+ val action = MotionEventCompat .getActionMasked(ev)
90+ Log .d(" ..." , " onTouch:$ev " )
91+ if (isTouching
92+ && isLongClick
93+ && action != MotionEvent .ACTION_CANCEL ) {
94+ handler.removeCallbacks(run)
95+ handler.post {
96+ onLongClicked?.invoke()
97+ }
98+ return true
99+ }
100+ when (action) {
101+ MotionEvent .ACTION_DOWN -> {
102+ isTouching = true
103+ startX = ev.x
104+ startY = ev.y
105+ moveX = ev.x
106+ moveY = ev.y
107+ touchDownTime = System .currentTimeMillis()
108+ }
109+ MotionEvent .ACTION_MOVE -> {
110+ moveX = ev.x
111+ moveY = ev.y
112+ }
113+ MotionEvent .ACTION_UP -> {
114+ isTouching = false
115+ handler.removeCallbacks(run)
116+ if (adapter.showState == ViewState .SELECT
117+ && ! isTouchLong()
118+ && isAClick()) {
119+ onClick?.invoke()
120+ }
121+ }
122+ MotionEvent .ACTION_CANCEL -> {
123+ isTouching = false
124+ handler.removeCallbacks(run)
125+ }
126+ }
127+ return true
128+ }
129+
130+
131+ fun setLongClickCallback (callback : () -> Unit ): Unit {
132+ onLongClicked = callback
133+ }
134+
135+ fun setSelectStateClickCallback (callback : () -> Unit ): Unit {
136+ onClick = callback
137+ }
138+
139+ private fun isInterceptLong () = System .currentTimeMillis() - downTime > CLICK_LONG_TIME
140+ private fun isTouchLong () = System .currentTimeMillis() - touchDownTime > CLICK_LONG_TIME
141+
142+ private fun isAClick (): Boolean {
143+ val differenceX = Math .abs(startX - moveX)
144+ val differenceY = Math .abs(startY - moveY)
145+ if (differenceX > CLICK_ACTION_THRESHHOLD /* =5 */ || differenceY > CLICK_ACTION_THRESHHOLD ) {
146+ return false
147+ }
148+ return true
149+ }
150+ }
0 commit comments