您当前的位置: 首页 >  ui

命运之手

暂无认证

  • 2浏览

    0关注

    747博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

【高级UI】【028】CoordinatorLayout源码解析和手动实现

命运之手 发布时间:2022-03-31 14:48:32 ,浏览量:2

CoordinatorLayout效果展示

在这里插入图片描述

CoordinatorLayout工作原理

CoordinatorLayout,可译为协调者布局,用于协调多个子View进行滑动交互

CoordinatorLayout实现滑动交互逻辑的核心是Behavior类,Behavior类规定子View间如何进行交互

CoordinatorLayout实现了一个自己的LayoutParam

CoordinatorLayout会为每个子View的LayoutParam设置一个Behavior

子View具体使用哪个Behavior,可以在xml布局中,通过自定义属性layout_behavior来指定

CoordinatorLayout在处理onTouchEvent时,会将事件转交给Behavior去处理,具体如何处理事件,是由Behavior中的逻辑来决定的

CoordinatorLayout交互动画

具体如何交互取决于Behavior代码,这里主要是介绍我们的Demo的动画逻辑

CoordinatorLayout包含三个子View,Text + Image + Toolbar

其中Text被NestedScrollView包裹,可以滑动

Toolbar在Image上层叠加显示,二者通过大小和透明度变化,形成滑动动画效果

默认状态:

Image完全展示,Toolbar透明度为0,Text滑动到顶端

Text向上滑动:

Toolbar透明度逐渐增加到100,Image逐渐变小,当Image和Toolbar一样大小时,不再变小,Toolbar透明度仍然继续增加

Text向下滑动:

Toolbar透明度逐渐减小到0,当Toolbar透明度为0时,Image逐渐变大,直到最大为止

NestedScrollView和CoordinatorLayout的关联

NestedScrollView是一个可以滚动的容器,它继承自FrameLayout,在基类的基础上增加了滑动功能

CoordinatorLayout继承自ViewGroup,它不处理任何布局功能,只是把布局工作转交给Behavior去处理

NestedScrollView和CoordinatorLayout联系起来的纽带在于

NestedScrollView实现了NestedScrollingChild接口,CoordinatorLayout实现了NestedScrollingParent接口

当Child进行滑动时,它会通知Parent,仅此而已

通过以上分析,我们基本可以确定这样一个事实

NestedScrollView仅负责滑动,CoordinatorLayout负责将布局事件和滑动事件等全部工作转发给子View

Behavior才是决定,子View如何进行布局,如何进行滑动交互的关键类

CoordinatorLayout的简单替代方案

其实,上面的动画,我们就算不用CoordinatorLayout,也可以很轻松地手动实现

无非就是监听ScrollView的滑动距离变化,然后控制Image大小和Toolbar透明度,这么简单的事情而已

其实CoordinatorLayout最终的工作,也就是这么简单而已

CoordinatorLayout出现的真正意义在于,它抽象了一套关于滑动交互逻辑的接口

使用CoordinatorLayout的话,全部的工作最后是交给Behavior去处理的

当我们需要使用新的子View,新的交互动画时,只要替换Behavior的实现类即可

可以看出,CoordinatorLayout的真正意义在于解耦,将交互动画的逻辑和控件解耦了,无需修改控件

如果我们用最简单的方法去实现,那么只要子View类型换一下,布局换一下,交互动画换一下,就得重新写一套控件

核心代码


	
	
	
	    
	
	    
	
	    
	
	        
	    
	


	@SuppressWarnings("all")
	public class CoordinatorLayout extends RelativeLayout implements NestedScrollingParent, ViewTreeObserver.OnGlobalLayoutListener {
	
	    float lastX;
	    float lastY;
	
	    public CoordinatorLayout(Context context) {
	        super(context);
	    }
	
	    public CoordinatorLayout(Context context, AttributeSet attrs) {
	        super(context, attrs);
	    }
	
	    public LayoutParams generateLayoutParams(AttributeSet attrs) {
	        return new LayoutParams(getContext(), attrs);
	    }
	
	    @Override
	    protected void onFinishInflate() {
	        super.onFinishInflate();
	        getViewTreeObserver().addOnGlobalLayoutListener(this);
	    }
	
	    @Override
	    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
	        super.onSizeChanged(w, h, oldw, oldh);
	        for (int i = 0; i             
关注
打赏
1654938663
查看更多评论
0.1402s