Android Design 自定义Behavior
2018-04-19 本文已影响218人
844b9a3a3a68
自从Android推出Design后,就广受各位开发者的喜爱,因为以前很多高级特效都需要我们自己去写,而现在Design库内置类很多实用的控件,很多复杂的需求用设个库就能满足,记得以前写自定义控件就经常遇到触摸事件方面的问题,比如外层ViewGroup将事件拦截后,在通过某些特定操作后,将事件还给内部子View处理,这种事件处理就很麻烦,因为在一次事件中外部ViewGroup一旦拦截了事件,子类就将无法再次接受这次事件,在处理某些组合操作时,显得不太流畅,而Design库中提供了一个神奇的控件CoordinatorLayout就能解决这类问题,CoordinatorLayout能将内部所有控件的事件串联起来,相互监听,让我们监听其他控件的状态,并执行自己对应的操作。
接下来我们先自定义一个Behavior,来达到下面演示的效果:
演示.gif从上面动图可以看出,这个动画实现非常简单,就是在AppBarLayout折叠的同时将底部栏慢慢移出屏幕,移动的数值就是AppBarLayout移动的值取反。
贴下布局文件:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="56dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|enterAlways|snap"
app:logo="@mipmap/ic_launcher"
app:navigationIcon="@mipmap/ic_launcher"
app:title="这是标题" />
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_gravity="bottom"
android:background="#ccc"
android:padding="8dp"
app:layout_behavior="view.peakchao.view.behavior.CustomExpandBehavior">
<Button
android:id="@+id/btn_send"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:background="@android:color/white"
android:text="发送" />
<EditText
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginRight="4dp"
android:layout_toLeftOf="@id/btn_send"
android:background="@android:color/white"
android:hint="你想说点什么?"
android:padding="4dp" />
</RelativeLayout>
<ImageView
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_marginBottom="70dp"
android:layout_marginRight="20dp"
android:src="@mipmap/ic_launcher"
app:layout_behavior="view.peakchao.view.behavior.DefineBehavior"
app:layout_scrollFlags="scroll|enterAlways|snap" />
</android.support.design.widget.CoordinatorLayout>
重点是上面布局中引用了app:layout_behavior这个属性,这个属性指定了当前View的行为:
//这个Behavior是系统自带的
app:layout_behavior="@string/appbar_scrolling_view_behavior"
//这个Behavior是接下来要自定义的
app:layout_behavior="view.peakchao.view.behavior.CustomExpandBehavior"
Behavior自定义的方式也很简单,首先确定我们要监听的View(这里是指AppBarLayout),然后被监听View发生变化时,处理我们需要做的操作。
/**
* Created by Chao 2018/4/17 on 9:42
* description
*/
public class CustomExpandBehavior extends CoordinatorLayout.Behavior {
public CustomExpandBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
/**
* 指定监听目标
*
* @param parent
* @param child
* @param dependency
* @return
*/
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
return dependency instanceof AppBarLayout;//这里我们需要监听AppBarLayout的状态。
}
/**
* 指定目标更新时候调用,layoutDependsOn返回true时有效
*
* @param parent
* @param child
* @param dependency
* @return
*/
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
int delta = dependency.getTop();
child.setTranslationY(-delta);//当AppBarLayout移动时,将当前View向反方向移动。
return true;
}
}
我们在布局中引用时,会两个参数的构造方法,当我们用注解设置Behavior时,会调用无参构造,比如我们上面用到的:
@CoordinatorLayout.DefaultBehavior(AppBarLayout.Behavior.class)
public class AppBarLayout extends LinearLayout {
}