待老夫kotlin大成,
众所周知,MotionLayout 的 动画是有完成度的 即Progress ,他在0-1之间变化,
一.CoordinatorLayout 与AppBarLayout 交互时,其实就是监听 offsetliner 这个 偏移量的变化 同样的 偏移量 也是 (0-1)
首先是 重写MotionLayout
class MyMotionToolBar @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : MotionLayout(context, attrs, defStyleAttr), AppBarLayout.OnOffsetChangedListener {
/**
* 以我目前的境界来看 这个类主要是 把MotionLaayout 和 AppbarLayout 关联起来
* 给他加了一个 addOnOffsetChangedListener
*/
override fun onAttachedToWindow() {
super.onAttachedToWindow()
(parent as? AppBarLayout)?.addOnOffsetChangedListener(this)
}
override fun onOffsetChanged(appBarLayout: AppBarLayout?, verticalOffset: Int) {
progress = -verticalOffset / appBarLayout?.totalScrollRange?.toFloat()!!
}
}
只需要你在正常使用的 时候写在 AppbarLayout 里直接使用
其实之前我是有另一套官方的代码,,,结果 不见了,,纳闷,为了说明这个关联progress
val ofFloat = ValueAnimator.ofFloat(0f, 1f)
ofFloat.setDuration(5000)
ofFloat.addUpdateListener(object : ValueAnimator.AnimatorUpdateListener{
override fun onAnimationUpdate(animation: ValueAnimator?) {
val fraction = animation!!.getAnimatedValue() as Float
motionLayout.progress=fraction
}
})
ofFloat.start()
就这样吧...
然后是DrawerLayout
同理
class MyMotionDrawer @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : MotionLayout(context, attrs, defStyleAttr), DrawerLayout.DrawerListener {
override fun onDrawerStateChanged(newState: Int) {
}
override fun onDrawerSlide(drawerView: View, slideOffset: Float) {
progress = slideOffset
}
override fun onDrawerClosed(drawerView: View) {
}
override fun onDrawerOpened(drawerView: View) {
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
(parent as DrawerLayout)?.addDrawerListener(this)
}
}
在DrawerLayout 设置 侧边栏的 代码中,直接替换根布局为自定义View
试着用了一下
三.ViewPager 交互
老套路
不需要重写了 可以直接监听你的 ViewPager ,
例如:
// 针对悬浮按钮
main_vp.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
var numPages = 5//总的页数
var progress = (position + positionOffset) / (numPages - 1)
my_viewpager_head.setProgress(progress)
}
override fun onPageSelected(position: Int) {
// var aposition = position
//
// if (aposition == 2) {// 2 is center
// aposition++// if page is 2, need set bottom item to 3, and the same to 3 -> 4
// }
if (position == 2) {
fab.setImageResource(R.drawable.btm3)
}else{
fab.setImageResource(R.drawable.btm3_false)
}
bnve.setCurrentItem(position)
}
override fun onPageScrollStateChanged(state: Int) {
}
})
可以直接监听 .这里也是 把 某一个进度 转换成 0-1的 形式 ,用这个0-1 设置 进度
这个套路可以 试一下 RecyclerView
rv.onFlingListener = object : RecyclerView.OnFlingListener() {
override fun onFling(velocityX: Int, velocityY: Int): Boolean {
return false
}
}
2019-08-26 11:18:46.092 28378-28378/com.as.flypig_kotlin I/System.out: velocityX :0 velocityY 436
2019-08-26 11:18:48.495 28378-28378/com.as.flypig_kotlin I/System.out: velocityX :0 velocityY 602
2019-08-26 11:18:50.954 28378-28378/com.as.flypig_kotlin I/System.out: velocityX :0 velocityY 1490
2019-08-26 11:18:52.348 28378-28378/com.as.flypig_kotlin I/System.out: velocityX :0 velocityY 4942
貌似每次滑动也有规律,但是看不懂,换一下
rv.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
}
/**
* //停止滚动
public static final int SCROLL_STATE_IDLE = 0;
//正在被外部拖拽,一般为用户正在用手指滚动
public static final int SCROLL_STATE_DRAGGING = 1;
//自动滚动开始
public static final int SCROLL_STATE_SETTLING = 2;
*/
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
if (motionlayout.currentState == motionlayout.startState) {
motionlayout.transitionToEnd()
} else {
motionlayout.transitionToStart()
}
}
}
})
完成度不知道咋搞... 等一个合适的需求?