最近项目中遇到个局部嵌套滑动的需求,实现后整理成demo
代码不多,就直接贴出来了。
需求:
1、一个界面,顶部有一块区域是 固定区域,不可以滑动;
2、中间有个内容介绍区域(控件);
3、下面是 viewpager+Fragment,多模块界面;
4、下面的 viewpager需要可以往上滑动,把内容介绍区域 顶走,固定区域不动。当 viewpager的tab到了 固定区域 的底部的时候,只能viewpager中Fragment里面的布局可以滑动
示例界面:
需要被顶走的区域
往上滑动时,把 内容介绍 布局顶走后的界面
数据列表可以滑动
---------- 分隔线 ----------
---------- 分隔线 ----------
功能实现
代码、界面的介绍
具体代码:这里就不详细说 MagicIndicator 了
1、颜色值
<color name="color_indicator_selected">#FF111111</color>
<color name="color_indicator_normal">#FF666666</color>
<color name="color_read">#ff0000</color>
2、JudgeNestedScrollView
import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.ViewConfiguration
import androidx.core.widget.NestedScrollView
import kotlin.math.abs
class JudgeNestedScrollView : NestedScrollView {
private var isNeedScroll = true
private var xDistance: Float = 0.toFloat()
private var yDistance: Float = 0.toFloat()
private var xLast: Float = 0.toFloat()
private var yLast: Float = 0.toFloat()
private var scaledTouchSlop: Int = 0
constructor(context: Context) : super(context, null) {
}
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs, 0) {
}
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
) {
scaledTouchSlop = ViewConfiguration.get(context).scaledTouchSlop
}
override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
when (ev.action) {
MotionEvent.ACTION_DOWN -> {
yDistance = 0f
xDistance = yDistance
xLast = ev.x
yLast = ev.y
}
MotionEvent.ACTION_MOVE -> {
val curX = ev.x
val curY = ev.y
xDistance += abs(curX - xLast)
yDistance += abs(curY - yLast)
xLast = curX
yLast = curY
return !(xDistance >= yDistance || yDistance < scaledTouchSlop) && isNeedScroll
}
}
try {
return super.onInterceptTouchEvent(ev)
} catch (e: Exception) {
return false
}
}
/*
该方法用来处理NestedScrollView是否拦截滑动事件
*/
fun setNeedScroll(isNeedScroll: Boolean) {
this.isNeedScroll = isNeedScroll
}
}
3、ViewPagerNoScrollHorizontally
import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.ViewConfiguration
import androidx.viewpager.widget.ViewPager
import kotlin.math.abs
class ViewPagerNoScrollHorizontally @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null
) :
ViewPager(context, attrs) {
private var downX = 0f
private var downY = 0f
var canScroll = false
override fun canScrollHorizontally(direction: Int): Boolean {
return canScroll
}
var isNestScrollChildEnable = true
override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
when(ev?.action){
MotionEvent.ACTION_DOWN -> {
downX = ev.x
downY = ev.y
}
MotionEvent.ACTION_MOVE -> {
val absDeltaX = abs(ev.x - downX)
val absDeltaY = abs(ev.y - downY)
if (absDeltaX > ViewConfiguration.get(context).scaledTouchSlop ||
absDeltaY > ViewConfiguration.get(context).scaledTouchSlop
) {
if (!isNestScrollChildEnable){
return true
}
}
}
MotionEvent.ACTION_UP,
MotionEvent.ACTION_CANCEL -> {
downX = 0f
downY = 0f
}
}
return super.onInterceptTouchEvent(ev)
}
}
4、ScaleTransitionPagerTitleView 指示器用
import android.content.Context;
import net.lucode.hackware.magicindicator.buildins.commonnavigator.titles.ColorTransitionPagerTitleView;
public class ScaleTransitionPagerTitleView extends ColorTransitionPagerTitleView {
private float mMinScale =