Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/origin/dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
luiing committed May 24, 2019
2 parents da19bd0 + fed18d5 commit 83a2971
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 82 deletions.
40 changes: 23 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,31 @@

4. 项目无偿使用,请注明出处和作者信息

### USE by Kotlin
implementation 'com.uis:adsorbent:0.1.3
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "com.android.support:recyclerview-v7:$supportVer"


``` 项目中使用的是compileOnly,使用者需自行加入外部依赖库 ```

### VERSION

Version|Descipt|Fixed|Time
----|----|----|----
0.1.1|初始版本| |2019/05/23
0.1.2|新增|快速滑动联动效果| |2019/05/24
0.1.3|更改|快速滑动联动处理| |2019/05/25

### USE
##### 事件分发ParentRecyclerView设置
/** true 开启滑动冲突处理(默认true)*/
recyclerView.enableConflict = true
/** 开启快速滚动parent带动child联动效果(默认false)*/
recyclerView.enableParentChain = false
/** 开启快速滚动child带动parent联动效果(默认true)*/
recyclerView.enableChildChain = true

##### Single
recyclerView.addOnScrollListener(object : SingleAdsorbentListener(){
/** 获取被吸顶ViewGroup*/
Expand Down Expand Up @@ -72,23 +95,6 @@
container.addView(view)
return view
}


### USE by Kotlin
implementation 'com.uis:adsorbent:0.1.2
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "com.android.support:recyclerview-v7:$supportVer"


``` 项目中使用的是compileOnly,使用者需自行加入外部依赖库 ```

### VERSION

Version|Descipt|Fixed|Time
----|----|----|----
0.1.1|初始版本| |2019/05/23
0.1.2|fixed快速滑动联动效果| |2019/05/24


### LICENSE
MIT License
Expand Down
1 change: 0 additions & 1 deletion adsorbent/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

android {
compileSdkVersion compileVer
Expand Down
20 changes: 3 additions & 17 deletions adsorbent/src/main/java/com/uis/adsorbent/ChildRecyclerView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,43 +20,29 @@ class ChildRecyclerView :RecyclerView{

/** true 开启滑动冲突处理*/
var enableConflict = true
/** 抬手动作记录滚动状态*/
private var actionUpState = SCROLL_STATE_IDLE
/** 记录上次的parent,避免递归频繁*/
private var parentView :WeakReference<OnInterceptListener>? = null

init {
addOnScrollListener(object :OnScrollListener(){
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
//Log.e("xx","child statechanged $newState, isTop="+!canScrollVertically(-1))
/** 滚动停止且到了顶部,快速滑动事件往上给parent view*/
if(SCROLL_STATE_IDLE == newState && !canScrollVertically(-1) && SCROLL_STATE_DRAGGING == actionUpState){
parentView?.get()?.let {
it.onScrollChain()
}
if(SCROLL_STATE_IDLE == newState && !canScrollVertically(-1)){
parentView?.get()?.onScrollChain()
}
}
})
}

override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
/** true child在顶部*/
if(enableConflict) {
induceParentOfChildTopStatus()
when(ev.action){
MotionEvent.ACTION_DOWN ->{
actionUpState = SCROLL_STATE_IDLE
}
MotionEvent.ACTION_UP -> {
actionUpState = scrollState
}
}
}
//Log.e("xx","child action ${ev.action} state $scrollState,y= ${ev.y}")
return super.dispatchTouchEvent(ev)
}

private fun induceParentOfChildTopStatus(){
/** true child在顶部*/
val isChildTop = !canScrollVertically(-1)
parentView?.get()?.let {
it.onTopChild(isChildTop)
Expand Down
91 changes: 44 additions & 47 deletions adsorbent/src/main/java/com/uis/adsorbent/ParentRecyclerView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import android.support.v7.widget.RecyclerView
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.VelocityTracker

class ParentRecyclerView :RecyclerView, OnInterceptListener {
constructor(context: Context) : super(context)
Expand All @@ -22,62 +23,55 @@ class ParentRecyclerView :RecyclerView, OnInterceptListener {
private var isChildTop = true
private var startdy = 0f
private var startdx = 0f
private var lastdy = 0f
private var enddy = 0f
private var lastTouchTime = 0L
private var needDispatchChild = true
private var needDispatchSelf = true
private var scrollValue = ArrayList<Float>(12)

/** 是否从吸顶后开始滑动*/
private var isStartSelfBottom = false
/** 抬手动作记录滚动状态*/
private var actionUpState = SCROLL_STATE_IDLE
private var velocity :VelocityTracker? = null
private var verticalSpeed = 0f

/** true 开启滑动冲突处理*/
var enableConflict = true
/** 开启快速滚动parent带动child联动效果(默认false)*/
var enableParentChain = false
/** 开启快速滚动child带动parent联动效果*/
var enableScrollChain = true
var enableChildChain = true

init {
/** parent带动child联动,此处违背吸顶原则*/
// addOnScrollListener(object :OnScrollListener(){
// override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
// Log.e("xx","parent statechanged $newState, isBottom="+!canScrollVertically(1))
// /** 滚动停止且到了底部,快速滑动事件下发给childview*/
// if(enableScrollChain && SCROLL_STATE_IDLE == newState && !canScrollVertically(1)
// && SCROLL_STATE_DRAGGING == actionUpState && scrollValue.size > 2){
// val manager = layoutManager
// if(manager is LinearLayoutManager){
// var realValue = 0f
// for(v in scrollValue){
// realValue += v
// dispatchChildTouch(manager,obtainMoveEvent(startdx,realValue))
// }
// dispatchChildTouch(manager,obtainUpEvent(startdx,realValue))
// }
// scrollValue.clear()
// }
// }
// })
addOnScrollListener(object :OnScrollListener(){
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
/** 滚动停止且到了底部,快速滑动事件下发给childview*/
if(enableParentChain && SCROLL_STATE_IDLE == newState && !canScrollVertically(1)
&& Math.abs(verticalSpeed) >= maxFlingVelocity/2){
val manager = layoutManager
if(manager is LinearLayoutManager){
val speed = Math.signum(verticalSpeed)*200
var dy = 2000f
for(i in 0 until 4){
dispatchChildTouch(manager,obtainMoveEvent(startdx,dy))
dy += speed
}
dispatchChildTouch(manager,obtainUpEvent(startdx,dy))
}
}
}
})
}

override fun onTopChild(isTop: Boolean) {
isChildTop = isTop
//Log.e("xx","onTopChild $isTop")
}

override fun onScrollChain() {
actionUpState = 0
if(enableScrollChain && !canScrollVertically(1) && scrollValue.size > 2) {
//Log.e("xx", "parent onScrollChain...")
var realValue = 0f
for (v in scrollValue) {
realValue += v
dispatchSelfTouch(obtainMoveEvent(startdx, realValue))
if(enableChildChain && isStartSelfBottom && Math.abs(verticalSpeed) >= maxFlingVelocity) {
val speed = Math.signum(verticalSpeed)*200
var dy = 1000f
for(i in 0 until 4){
dispatchSelfTouch(obtainMoveEvent(startdx, dy))
dy += speed
}
dispatchSelfTouch(obtainUpEvent(startdx, realValue))
scrollValue.clear()
dispatchSelfTouch(obtainUpEvent(startdx, dy))
}
}

Expand All @@ -86,7 +80,10 @@ class ParentRecyclerView :RecyclerView, OnInterceptListener {
}

private fun dispatchConflictTouchEvent(ev: MotionEvent):Boolean{
val now = SystemClock.currentThreadTimeMillis()
if(velocity == null){
velocity = VelocityTracker.obtain()
}
velocity?.addMovement(ev)
when(ev.action){
MotionEvent.ACTION_DOWN ->{
startdx = ev.x
Expand All @@ -95,24 +92,22 @@ class ParentRecyclerView :RecyclerView, OnInterceptListener {
needDispatchChild = true
needDispatchSelf = true
isStartSelfBottom = !canScrollVertically(1)
scrollValue.clear()
scrollValue.add(startdy)
verticalSpeed = 0f
}
MotionEvent.ACTION_MOVE ->{
scrollValue.add( (ev.y-lastdy)/(now-lastTouchTime))
if(conflictMoveEvent(ev)){
lastdy = ev.y
lastTouchTime = now
return true
}
}
MotionEvent.ACTION_UP ->{
actionUpState = scrollState
enddy = (ev.y-lastdy)/(now-lastTouchTime)
velocity?.let {
it.computeCurrentVelocity(1000, maxFlingVelocity.toFloat())
verticalSpeed = it.getYVelocity()
}
velocity?.recycle()
velocity = null
}
}
lastdy = ev.y
lastTouchTime = now
//Log.e("xx","parent action= ${ev.action} ,state= $scrollState ,y= ${ev.y}, isBotton="+!canScrollVertically(1))
return false
}
Expand Down Expand Up @@ -164,6 +159,7 @@ class ParentRecyclerView :RecyclerView, OnInterceptListener {
if(needDispatchSelf) {
needDispatchSelf = false
onTouchEvent(obtainDownEvent(ev.x, ev.y))
SystemClock.sleep(2)
}
onTouchEvent(ev)
}
Expand All @@ -176,6 +172,7 @@ class ParentRecyclerView :RecyclerView, OnInterceptListener {
if (needDispatchChild) {
needDispatchChild = false
it.dispatchTouchEvent(obtainDownEvent(ev.x, ev.y))
SystemClock.sleep(2)
}
it.dispatchTouchEvent(ev)
}
Expand Down

0 comments on commit 83a2971

Please sign in to comment.