上篇文章我们讲到,在CoordinatorLayout中,一个View可以根据另一个View的变化而变化,而提供这种关联关系的类就是Behavior。仅为了描述上的方便,在这篇文章中称呼这两个View为主动View和被动View。
一、基本用法
首先来看效果:
蓝色方块随着黄色方块的变化而变化要实现这个Demo,首先要了解下Behavior类,在AS里面点进去看下:
Behavior类
Behavior是CoordinatorLayout的内部抽象类
public static abstract class Behavior<V extends View> {
Behavior定义了一个View的子类泛型,这个类指的是被动View。
Behavior的核心方法都是onXXX之类的回调,如最基础的onDependentViewChanged方法,在主动View的大小或者位置发生变化时会回调这个方法。而onNestedFling方法会在主动View fling时回调这个方法。
除此之外layoutDependsOn也是几乎必须要被覆写的方法,它定义了被动View所依赖的主动View是谁,每次CoordinatorLayout布局时,这个方法都会被调用(调用的次数为他的子View的个数减去被动View的个数)。当参数中的dependency是正确的主动View时,这个方法需要返回true,否则返回false。
public boolean layoutDependsOn(CoordinatorLayout parent, V child, View dependency) {
return false;
}
另外,如果要在xml中声明Behavior时,需要覆写构造函数。在xml中为被动View声明Behavior的方法是:
app:layout_behavior="com.sg.line.MyBehavior"
下面来实现Demo,首先写主动View ,那个黄色小方块,让他跟随手指移动,正常写就行了:
public class DragableIV extends android.support.v7.widget.AppCompatImageView {
public DragableIV(Context context) {
super(context);
}
public DragableIV(Context context, AttributeSet attrs) {
super(context, attrs);
}
public DragableIV(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
float xDown, yDown, x, y;
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
x = getX();
y = getY();
xDown = event.getRawX();
yDown = event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
setX(x + (event.getRawX() - xDown));
setY(y + (event.getRawY() - yDown));
break;
}
return true;
}
}
然后是布局(注意用app:layout_behavior为被动View指定Behavior):
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<com.sg.line.DragableIV
android:id="@+id/ivMove"
android:background="@android:color/holo_orange_light"
android:layout_width="50dp"
android:layout_height="50dp"/>
<TextView
app:layout_behavior="com.sg.line.MyBehavior"
android:layout_gravity="bottom"
android:id="@+id/tvFollow"
android:background="@android:color/holo_blue_bright"
android:layout_width="50dp"
android:layout_height="50dp"/>
</android.support.design.widget.CoordinatorLayout>
最后是Behavior:
public class MyBehavior extends CoordinatorLayout.Behavior<TextView> {
public MyBehavior() {
}
public MyBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, TextView child, View dependency) {
return dependency instanceof DragableIV;
}
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, TextView child, View dependency) {
child.setX(dependency.getX());
child.setY(parent.getHeight() - dependency.getY() - dependency.getHeight());
return true;
}
}
在layoutDependsOn方法中,指定被动View对应的主动View为DragableIV实例;
在onDependentViewChanged,让被动View的x等同于主动View,y和主动View垂直对称。如果在这个方法中被动view的大小或者位置也发生了改变则返回true,否则返回false,这里肯定是要返回true的。
这样全部的代码就写完了,是不是很简单。
网友评论