CoordinatorLayout是什么,作用是什么?它是作为顶层布局,用来协调子View。
例如效果图:
蓝色部分是自定义控件,黄色的是一个Button,当我们移动蓝色控件的时候,黄色控件按照蓝色控件相反方向运动。实现这个效果的方式有很多,但是使用CoordinatorLayou会很简单,并且两个控件之间完全解耦了。
CoordinatorLayout使用新的思路通过协调调度子View的形式实现触摸影响布局的形式产生动画效果。CoordinatorLayout是通过设置子View的Behavior来实现,在讲Behavior之前需要了解两个概念,child,dependency。
child是CoordinatorLayout的子View,dependency是child所依赖的控件,在这里就是蓝色控件。
黄色Button所代表的child需要依赖蓝色控件所代表的dependency运动。
自定义控件:MyLayoutView,这个控件可以随便滑动。
public class MyLayoutView extends View {
private int lastX;
private int lastY;
private int screenWidth;
private int screenHeight;
public MyLayoutView(Context context) {
super(context);
}
public MyLayoutView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getRawX();
int y = (int) event.getRawY();
DisplayMetrics display = getContext().getResources().getDisplayMetrics();
screenWidth = display.widthPixels;
screenHeight = display.heightPixels;
switch (event.getAction()){
case MotionEvent.ACTION_MOVE:
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) getLayoutParams();
int left = params.leftMargin+x-lastX;
int top = params.topMargin+y-lastY;
if(left<0){
left = 0;
}else if(left>screenWidth){
left = screenWidth;
}else if(top<0){
top = 0;
}
else if(top>screenHeight){
top = screenHeight;
}
params.leftMargin = left;
params.topMargin = top;
setLayoutParams(params);
break;
default:break;
}
lastX = x;
lastY = y;
return true;
}
}
制作Behavior,在这里可以设置child所依赖的控件,并且设置child应该怎样随着dependency运动。
public class MyBehavior extends CoordinatorLayout.Behavior<Button> {
private int width;
private int height;
public MyBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
DisplayMetrics display = context.getResources().getDisplayMetrics();
width = display.widthPixels;
int identifier = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
if(identifier>0){
int dimensionPixelSize = context.getResources().getDimensionPixelSize(identifier);
height = display.heightPixels - dimensionPixelSize;
}
}
/**
* 判断所依赖的dependency
*/
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, Button child, View dependency) {
//如果dependency是TempView的实例,说明它就是我们所需要的Dependency
return dependency instanceof MyLayoutView;
}
//每次dependency位置发生变化,都会执行onDependentViewChanged方法
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, Button btn, View dependency) {
//根据dependency的位置,设置Button的位置
int top = dependency.getTop();
int left = dependency.getLeft();
int x = width - left- btn.getWidth();
int y = height - top - btn.getHeight();
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);
}
}
布局:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Button
android:id="@+id/btn"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#FFCC00"
app:layout_behavior="cn.centran.androidsdata.MyBehavior"/>
<cn.centran.androidsdata.view.MyLayoutView
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#3366CC"
android:tag="10"
/>
</android.support.design.widget.CoordinatorLayout>