CoordinatorLayout_Behavior控制Toolbar&Fab的显示和隐藏
Posted 花花young
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CoordinatorLayout_Behavior控制Toolbar&Fab的显示和隐藏相关的知识,希望对你有一定的参考价值。
前言
Behavior是android新出的Design库里新增的布局概念。Behavior只有是CoordinatorLayout的直接子View才有意义。可以为任何View添加一个Behavior。Behavior是一系列回调。让你有机会以非侵入的为View添加动态的依赖布局,和处理父布局(CoordinatorLayout)滑动手势的机会。
效果~
Part 1、利用监听事件来实现显示和隐藏动画
布局
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.andly.administrator.andly_md9.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
android:paddingTop="?attr/actionBarSize"
/>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"/>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:src="@android:drawable/ic_dialog_email"
android:layout_margin="16dp"
app:elevation="10dp"
app:fabSize="normal"
app:pressedTranslationZ="12dp"
app:rippleColor="#ff0"
/>
</RelativeLayout>
为RecyclerView设置监听事件
rv.addOnScrollListener(new FabScrollListener(this));
public class FabScrollListener extends RecyclerView.OnScrollListener
private int distance = 0;//滑动的距离,根据距离于临界值比较判断是向上滑还是向下滑
private HideScrollListener hideListener;//这里使用监听让Activity进行实现
private boolean visible = true;//是否可见
public FabScrollListener(HideScrollListener hideScrollListener)
// TODO Auto-generated constructor stub
this.hideListener = hideScrollListener;
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy)
super.onScrolled(recyclerView, dx, dy);
//dy有正有负,向上滑为负 向下滑为正
if (distance < -ViewConfiguration.getTouchSlop() && !visible)
//显示Fab和ToolBar
hideListener.onShow();
distance = 0;
visible = true;
else if (distance > ViewConfiguration.getTouchSlop() && visible)
//隐藏Fab和ToolBar
hideListener.onHide();
distance = 0;
visible = false;
if ((dy > 0 && visible) || (dy < 0 && !visible))//向下滑并且可见 或者 向上滑并且不可见
distance += dy;
这里通过distance和visible的判断来实现toolbar和fab的显示和隐藏
相应的实现
@Override
public void onHide()
mToolbar.animate().translationY(-mToolbar.getHeight()).setInterpolator(new AccelerateInterpolator(3));
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) fab.getLayoutParams();
ViewCompat.animate(fab).translationY(fab.getHeight() + layoutParams.bottomMargin + layoutParams.topMargin).setInterpolator(new AccelerateInterpolator(3));
@Override
public void onShow()
mToolbar.animate().translationY(0).setInterpolator(new DecelerateInterpolator(3));
ViewCompat.animate(fab).translationY(0).setInterpolator(new DecelerateInterpolator(3));
效果~
Part 2、Behavior控制Toolbar&Fab的显示和隐藏
CoordinatorLayout继承ViewGroup,通过协调并调度里面的子控件来实现触摸并产生一些相关的动画,可以通过设置View的Behavior来实现触摸的动画调度
布局
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.andly.administrator.andly_md9.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="?attr/actionBarSize"
/>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"/>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:src="@android:drawable/ic_dialog_email"
app:elevation="10dp"
app:fabSize="normal"
app:layout_behavior=".FabBehavior"
app:pressedTranslationZ="12dp"
app:rippleColor="#ff0"/>
</android.support.design.widget.CoordinatorLayout>
tips:
1、要用CoordinatorLayout进行包裹
2、app:layout_behavior="包名+类名" 这里注意的是在Behavior子类加上构造方法
public FabBehavior(Context context, AttributeSet attrs)
super();
不然会报Could not inflate Behavior subclass异常
相应的自定义Behavior,这里继承的是FloatingActionButton.Behavior类
public class FabBehavior extends FloatingActionButton.Behavior
private boolean visible = true;//是否可见
public FabBehavior(Context context, AttributeSet attrs)
super();
@Override
public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout,
FloatingActionButton child, View directTargetChild, View target,
int nestedScrollAxes)
return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL || super.onStartNestedScroll(coordinatorLayout, child, directTargetChild,
target, nestedScrollAxes);
@Override
public void onNestedScroll(CoordinatorLayout coordinatorLayout,
FloatingActionButton child, View target, int dxConsumed,
int dyConsumed, int dxUnconsumed, int dyUnconsumed)
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed,
dxUnconsumed, dyUnconsumed);
if (dyConsumed > 0 && visible)
//show
visible = false;
onHide(child, (Toolbar) coordinatorLayout.getChildAt(1));
else if (dyConsumed < 0)
//hide
visible = true;
onShow(child, (Toolbar) coordinatorLayout.getChildAt(1));
public void onHide(FloatingActionButton fab, Toolbar toolbar)
toolbar.animate().translationY(-toolbar.getHeight()).setInterpolator(new AccelerateInterpolator(3));
CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) fab.getLayoutParams();
fab.animate().translationY(fab.getHeight() + layoutParams.bottomMargin).setInterpolator(new AccelerateInterpolator(3));
public void onShow(FloatingActionButton fab, Toolbar toolbar)
toolbar.animate().translationY(0).setInterpolator(new DecelerateInterpolator(3));
fab.animate().translationY(0).setInterpolator(new DecelerateInterpolator(3));
tips:
1、onStartNestedScroll() : 当观察的View滑动开始的时候进行回调
2、onNestedScroll() : 当观察的View滑动的时候回调
3、nestedScrollAxes : 滑动的关联轴,这里只考虑竖直方向
当然你可以使用github上第三方库https://github.com/makovkastar/FloatingActionButton
步骤:
1、添加依赖
dependencies
compile 'com.melnykov:floatingactionbutton:1.3.0'
2、在布局中引用自定义FloatingActionButton
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:fab="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.melnykov.fab.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_margin="16dp"
android:src="@drawable/ic_action_content_new"
fab:fab_colorNormal="@color/primary"
fab:fab_colorPressed="@color/primary_pressed"
fab:fab_colorRipple="@color/ripple" />
</FrameLayout>
3、关联Fab到ScrollView、ListView、RecyclerView
ListView listView = (ListView) findViewById(android.R.id.list);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.attachToListView(listView);
4、在布局中设置
fab:fab_type="mini"
fab:fab_colorNormal="@color/primary"
fab:fab_colorPressed="@color/primary_pressed"
fab:fab_shadow="false"
fab:fab_colorRipple="@color/ripple"
或者在代码中进行设置
fab.setType(FloatingActionButton.TYPE_MINI);
fab.setColorNormal(getResources().getColor(R.color.primary));
fab.setColorPressed(getResources().getColor(R.color.primary_pressed));
fab.setShadow(false);
fab.show();
fab.hide();
fab.show(false); // Show without an animation
fab.hide(false); // Hide without an animation
fab.setColorRipple(getResources().getColor(R.color.ripple));
以上是关于CoordinatorLayout_Behavior控制Toolbar&Fab的显示和隐藏的主要内容,如果未能解决你的问题,请参考以下文章