android 依赖布局,Android开发 之 (协调布局)CoordinatorLayout与(依赖行为)Behavior...

本文详细介绍了Android中的CoordinatorLayout和Behavior的使用,包括它们如何创建依赖关系以实现组件间的交互,如通过Behavior处理滑动事件来实现类似CollapsingToolbarLayout的效果。Behavior的两种主要用途是坐标依赖和滑动事件处理,通过自定义Behavior可以实现复杂的布局动态效果和交互体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CoordinatorLayout与Behavior

翻译过来就是协调布局和依赖行为,这两个是内部类关系

在我这里有两种用途:看效果

0b63cfe7a783fea4d3e6b68a4d62a3af.png

第一种,两个空间的y坐标形成依赖关系,坐标依赖

2e08c62552c6928dce11214fc304c6f9.png

第二种,滑动以来关系

上代码:

第一种:

当然了这种效果是基于协调布局开发的,所以布局必须使用协调布局

代码中button添加一个属性layout_behavior就是建立以来关系的属性,MyBehavior这个类是自定义的,这里属性值:自定义的类的包名+类名。

自定义的MyBehavior类:

package com.example.zxq.bsquxian.views;

import android.content.Context;

import android.support.design.widget.CoordinatorLayout;

import android.util.AttributeSet;

import android.view.View;

import android.widget.Button;

/**

* Created by Administrator on 2017/7/25 0025.

*/

public class MyBehavior extends CoordinatorLayout.Behavior{

public MyBehavior(Context context, AttributeSet attrs)

{

super(context,attrs);

}

@Override

public boolean layoutDependsOn(CoordinatorLayout parent, Button child, View dependency) {

//如果dependency 是 ScrPositionTextView, 就依赖

return dependency instanceof ScrPositionTextView;

}

//每次dependency位置发生变化,都会执行onDependentViewChanged方法

@Override

public boolean onDependentViewChanged(CoordinatorLayout parent, Button btn, View dependency) {

//根据dependency的位置,设置Button的位置

int x = 0;

int y = (int) dependency.getY();

setPosition(btn, x, y);

return true;

}

private void setPosition(View v, int x, int y) {

CoordinatorLayout.MarginLayoutParams layoutParams = (CoordinatorLayout.MarginLayoutParams) v.getLayoutParams();

layoutParams.leftMargin = x;

layoutParams.topMargin = y;

v.setLayoutParams(layoutParams);

}

}在上面的layoutDependsOn方法中判断依赖对象,要依赖到哪个组件上。这里依赖了一个自定义TextView,当然这里也可以通过id判断依赖关系

自定义的TextView:

package com.example.zxq.bsquxian.views;

import android.content.Context;

import android.support.annotation.Nullable;

import android.support.design.widget.CoordinatorLayout;

import android.util.AttributeSet;

import android.util.Log;

import android.view.MotionEvent;

import android.widget.TextView;

/**

* Created by Administrator on 2017/7/25 0025.

*/

public class ScrPositionTextView extends android.support.v7.widget.AppCompatTextView {

private int startx;

private int starty;

public ScrPositionTextView(Context context) {

super(context);

}

public ScrPositionTextView(Context context, @Nullable AttributeSet attrs) {

super(context, attrs);

}

public ScrPositionTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

}

@Override

public boolean onTouchEvent(MotionEvent event) {

switch (event.getAction())

{

case MotionEvent.ACTION_DOWN:

startx= (int) event.getRawX();

starty= (int) event.getRawY();

break;

case MotionEvent.ACTION_MOVE:

int lastX= (int) event.getRawX();

int lastY= (int) event.getRawY();

int movex= lastX-startx;

int movey= lastY-starty;

startx= lastX;

starty= lastY;

CoordinatorLayout.MarginLayoutParams layoutParams= (CoordinatorLayout.MarginLayoutParams) getLayoutParams();

int left = layoutParams.leftMargin+movex;

int top = layoutParams.topMargin+movey;

layoutParams.leftMargin=left;

layoutParams.topMargin=top;

setLayoutParams(layoutParams);

requestFocus();

break;

}

return true;

}

}这里动态改变textview的位置就ok,自己的y坐标会自动关联到那个button上去的。

第二种代码:

Behavior最大的用处在于对滑动事件的处理。就像CollapsingToolbarLayout的那个酷炫效果一样。

自定义的Behavior:这里需要重写以下几个方法

package com.example.zxq.bsquxian.views;

import android.content.Context;

import android.support.design.widget.CoordinatorLayout;

import android.util.AttributeSet;

import android.view.MotionEvent;

import android.view.View;

/**

* Created by Administrator on 2017/7/27 0027.

*/

public class ScrollBehavior extends CoordinatorLayout.Behavior {

int offsetTotal = 0;

boolean scrolling = false;

public ScrollBehavior(Context context, AttributeSet attrs) {

super(context, attrs);

}

@Override

public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {

return true;//这里返回true,才会接受到后续滑动事件。

}

@Override

public void onNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {

//进行滑动事件处理

offset(child,dyConsumed);

}

@Override

public boolean onNestedFling(CoordinatorLayout coordinatorLayout, View child, View target, float velocityX, float velocityY, boolean consumed) {

//当进行快速滑动

return super.onNestedFling(coordinatorLayout, child, target, velocityX, velocityY, consumed);

}

@Override

public boolean onInterceptTouchEvent(CoordinatorLayout parent, View child, MotionEvent ev) {

return super.onInterceptTouchEvent(parent, child, ev);

}

@Override

public boolean onTouchEvent(CoordinatorLayout parent, View child, MotionEvent ev) {

return super.onTouchEvent(parent, child, ev);

}

public void offset(View child,int dy){

int old = offsetTotal;

int top = offsetTotal - dy;

top = Math.max(top, -child.getHeight());

top = Math.min(top, 0);

offsetTotal = top;

if (old == offsetTotal){

scrolling = false;

return;

}

int delta = offsetTotal-old;

child.offsetTopAndBottom(delta);

scrolling = true;

}

}

布局文件;

注意被依赖的View只有实现了NestedScrollingChild接口的才可以将事件传递给CoordinatorLayout。

但注意这个滑动事件是对于CoordinatorLayout的。所以只要CoordinatorLayout有NestedScrollingChild就会滑动,他滑动就会触发这几个回调。无论你是否依赖了那个View。

Imageview设置关联属性

有关自己的事件处理可以在这2个回调与View中的事件分发是一样的。所有Behavior能在子View之前收到CoordinatorLayout的所有触摸事件。可以进行拦截,如果拦截事件将不会流经子View。因为这2个方法都是在CoordinatorLayout的 回调中

其实之前讲的AppBarLayout效果也是这个原理:

AppBarLayout自带一个Behivior。直接在源码里注解声明的。这个Behivior也只能用于AppBarLayout。

作用是让他根据CoordinatorLayout上的滚动手势进行一些效果(比如收缩)。与ScrollingViewBehavior是无关的,加不加ScrollingViewBehavior不影响收缩。

只不过只有某些可滑动View才会把滑动事件响应给CoordinatorLayout才能继而响应给AppBarLayout。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值