本文已参加「新人创作礼」活动,一起开启掘金创作之路。
定义接口
/**
* 滑动状态监听 : 滑动/静止
*/
interface OnScrollStateListener {
/**
* true : 滑动
* false : 静止
*/
fun scrollState(isScrolling: Boolean)
}
/**
* 滑动位置监听
*
* SCROLL_TOP 滑动到顶部
* SCROLL_MIDDLE 滑动到不是顶部不是底部
* SCROLL_BOTTOM 滑动到底部
*/
interface OnScrollPositionListener {
fun scrollPosition(position: Int)
}
/**
* 滑动方向监听
*
* 垂直布局 : 向上/向下
*/
interface OnScrollDirectionVerticalListener {
//向上滑动
fun scrollUp(dy: Int = 0)
//向下滑动
fun scrollDown(dy: Int = 0)
}
/**
* 滑动方向监听
*
* 水平布局 : 向左/向右
*/
interface OnScrollDirectionHorizonListener {
//向左滑动
fun scrollLeft(d: Int = 0)
//向右滑动
fun scrollRight(dx: Int = 0)
}
定义滑动监听器
class RecycleScrollListener(private var layoutStyle: Int = LAYOUT_STYLE_VERTICAL) :
RecyclerView.OnScrollListener() {
companion object {
/**
* SCROLL_TOP 滑动到顶部
* SCROLL_MIDDLE 滑动到不是顶部不是底部
* SCROLL_BOTTOM 滑动到底部
*/
const val SCROLL_TOP = 1
const val SCROLL_MIDDLE = 0
const val SCROLL_BOTTOM = -1
/**
* LAYOUT_STYLE_VERTICAL 垂直布局
* LAYOUT_STYLE_HORIZON 水平布局
*/
const val LAYOUT_STYLE_VERTICAL = 1001
const val LAYOUT_STYLE_HORIZON = 1002
}
/**
* mOnStateListener 滑动状态监听
* mOnPositionListener 滑动位置监听
* mOnVerticalListener 滑动方向监听 - 垂直布局
* mOnHorizonListener 滑动方向监听 - 水平布局
*/
private var mOnStateListener: OnScrollStateListener? = null
private var mOnPositionListener: OnScrollPositionListener? = null
private var mOnVerticalListener: OnScrollDirectionVerticalListener? = null
private var mOnHorizonListener: OnScrollDirectionHorizonListener? = null
/**
* 设置滑动状态监听
*/
public fun setOnScrollStateListener(listener: OnScrollStateListener) {
mOnStateListener = listener
}
/**
* 设置滑动位置监听
*/
public fun setOnScrollPositionListener(listener: OnScrollPositionListener) {
mOnPositionListener = listener
}
/**
* 设置滑动方向监听 - 垂直布局
*/
public fun setOnScrollDirectionVerticalListener(listener: OnScrollDirectionVerticalListener) {
mOnVerticalListener = listener
}
/**
* 设置滑动方向监听 - 水平布局
*/
public fun setOnScrollDirectionHorizonListener(listener: OnScrollDirectionHorizonListener) {
mOnHorizonListener = listener
}
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
//滑动状态
mOnStateListener?.let {
if (recyclerView.scrollState == 0) {
//未滑动
it.scrollState(false)
} else {
//滑动中
it.scrollState(true)
}
}
//滑动位置
mOnPositionListener?.let {
if (layoutStyle == LAYOUT_STYLE_HORIZON) {
//水平布局
if (!recyclerView.canScrollHorizontally(-1)) {
//滑动到顶部
it.scrollPosition(SCROLL_TOP)
} else if (!recyclerView.canScrollHorizontally(1)) {
//滑动到底部
it.scrollPosition(SCROLL_BOTTOM)
} else {
//滑动到非顶部非底部
it.scrollPosition(SCROLL_MIDDLE)
}
} else {
//默认垂直布局
if (!recyclerView.canScrollVertically(-1)) {
//滑动到顶部
it.scrollPosition(SCROLL_TOP)
} else if (!recyclerView.canScrollVertically(1)) {
//滑动到底部
it.scrollPosition(SCROLL_BOTTOM)
} else {
//滑动到非顶部非底部
it.scrollPosition(SCROLL_MIDDLE)
}
}
}
//滑动方向 - 垂直布局
mOnVerticalListener?.let {
if (dy < 0) {
//向上滑动
it.scrollUp(dy)
} else if (dy > 0) {
//向下滑动
it.scrollDown(dy)
}
}
//滑动方向 - 水平布局
mOnHorizonListener?.let {
if (dx < 0) {
//向左滑动
it.scrollLeft(dx)
} else if (dx > 0) {
//向右滑动
it.scrollRight(dx)
}
}
}
}
在Activity中使用监听器
fun initRecyclerView() {
val layoutManager = LinearLayoutManager(this)
layoutManager.orientation = RecyclerView.VERTICAL
val adapter = RecycleViewAdapter()
adapter.setData(getData())
val scrollListener = RecycleScrollListener()
scrollListener?.let {
//滑动状态
it.setOnScrollStateListener(object : OnScrollStateListener {
override fun scrollState(isScrolling: Boolean) {
TODO("Not yet implemented")
}
})
//滑动位置
it.setOnScrollPositionListener(object : OnScrollPositionListener {
override fun scrollPosition(position: Int) {
when (position) {
RecycleScrollListener.SCROLL_TOP -> Log.i(TAG, "滑动到顶部")
RecycleScrollListener.SCROLL_BOTTOM -> Log.i(TAG, "滑动到底部")
else -> Log.i(TAG, "滑动到非顶部非底部")
}
}
})
//滑动方向 - 垂直布局
it.setOnScrollDirectionVerticalListener(object : OnScrollDirectionVerticalListener {
override fun scrollUp(dy: Int) {
Log.i(TAG, "向上滑动的距离 $dy")
}
override fun scrollDown(dy: Int) {
Log.i(TAG, "向下滑动的距离 $dy")
}
})
}
mRecyclerView?.let {
it.layoutManager = layoutManager
it.adapter = adapter
it.addOnScrollListener(scrollListener)
}
}