Behavior是Android新出的Design库里新增的布局概念。Behavior只有是CoordinatorLayout的直接子View才有意义。可以为任何View添加一个Behavior。
Behavior是一系列回调。让你有机会以非侵入的为View添加动态的依赖布局,和处理父布局(CoordinatorLayout)滑动手势的机会。如果我们想实现控件之间任意的交互效果,完全可以通过自定义 Behavior 的方式达到。
Behavior是CoordinatorLayout的一个抽象内部类
public abstract static class Behavior<V extends View> {
public Behavior() {
}
public Behavior(Context context, AttributeSet attrs) {
}
...
}
1,官方BottomSheetBehavior使用
app:behavior_hideable="true"
app:behavior_peekHeight="0dp"
app:layout_behavior="@string/bottom_sheet_behavior">
public void onCl(View view) {
BottomSheetBehavior behavior = BottomSheetBehavior.from(findViewById(R.id.scroll));
if(behavior.getState() == BottomSheetBehavior.STATE_EXPANDED) {
behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}else {
behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}
}
// BottomSheetDialog
/* BottomSheetDialog sheetDialog = new BottomSheetDialog();
sheetDialog.setContentView(view);
sheetDialog.show();*/
//setBottomSheetCallback
/* behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
}
});*/
2,自定义Behavior
我们可以按照两种目的来实现自己的Behavior,当然也可以两种都实现啦
某个view监听另一个view的状态变化,例如大小、位置、显示状态等
某个view监听CoordinatorLayout内的NestedScrollingChild的接口实现类的滑动状态
第一种情况需要重写layoutDependsOn和onDependentViewChanged方法
第二种情况需要重写onStartNestedScroll和onNestedPreScroll系列方法
如果你的自定义View默认使用一个Behavior。
在你的自定义View类上添加@DefaultBehavior(你的Behavior.class)这句注解。
你的View就默认使用这个Behavior。就像AppBarLayout一样。
@DefaultBehavior(AppBarLayout.Behavior.class)
public class AppBarLayout extends LinearLayout {
}
第一种情况
现在我们就来根据第一种情况尝试自定义一个Behavior,这里我们实现一个简单的效果,让一个View根据另一个View上下移动。
public class DependencyBehavior extends CoordinatorLayout.Behavior<View> {
public DependencyBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
return dependency instanceof Button;
}
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
int offset = dependency.getTop();
ViewCompat.offsetTopAndBottom(child, -offset);
return true;
}
}
我们覆写了两个方法layoutDependsOn和onDependentViewChanged,这两个方法的参数都是一样的,解释一下,第一个不用说,就是当前的CoordinatorLayout,第二个参数是我们设置这个Behavior的View,第三个是我们关心的那个View。如何知道关心的哪个呢?layoutDependsOn的返回值决定了一切!
return dependency instanceof Button; 关心所有Button的变化。
return dependency.getId()==R.id.Btn; 关心id为R.id.Btn的变化。
现在设置好了关心谁,接下来就是在这个View状态发生变化的时候,我们现在的View该做些什么了,这里肯定是在onDependentViewChanged做工作了。我们的任务就是获取dependency距离顶部的距离,并且设置给child。
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
int offset = dependency.getTop();
ViewCompat.offsetTopAndBottom(child, -offset);
return true;
}
在XM