先来看一段谷歌官方对FAB的解释http://www.google.co.in/design/spec/components/buttons-floating-action-button.html#buttons-floating-action-button-floating-action-button
我简单归纳一下文中所说的几个重点:
1.不是每个app 都需要FAB,如果需要的话最多也是只要一个FAB即可。
2.FAB的icon应该是表示一个动词,而不能是一个名词。
比如我们可以这样:
但是不能这样:
3.FAB必须得是圆形的icon 不能是其他样子。并且只能是2d平面图。不能带有3d的投影之类的效果
好我们来看一下FAB的简单使用
xml文件
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:app="http://schemas.android.com/apk/res-auto" 3 xmlns:tools="http://schemas.android.com/tools" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent" 6 android:paddingBottom="@dimen/activity_vertical_margin" 7 android:paddingLeft="@dimen/activity_horizontal_margin" 8 android:paddingRight="@dimen/activity_horizontal_margin" 9 android:paddingTop="@dimen/activity_vertical_margin" 10 tools:context=".MainActivity"> 11 12 <FrameLayout 13 android:id="@+id/layout" 14 android:layout_width="match_parent" 15 android:layout_height="match_parent"> 16 17 <android.support.design.widget.FloatingActionButton 18 android:id="@+id/fabutton" 19 android:layout_width="wrap_content" 20 android:layout_height="wrap_content"> 21 22 </android.support.design.widget.FloatingActionButton> 23 24 25 </FrameLayout> 26 27 28 </RelativeLayout>
看一下运行的效果:
当然也可以改变位置FAB的位置,因为FAB一般情况下都在右下角落
再加一些属性
看看所谓的按下去的波纹效果:
然后看一下另外一个特殊的效果,很多GOOGLE 官方的app里面 FAB和listview 在一起的时候会有额外的效果,
比如listview 往下拉的时候 FAB才显示 往上滑的时候就不显示 这个效果放在以前是不太好做的,
但是更新了这个新的官方库以后这个效果就比较好做了。
首先你要使用新的 Recyclerview这个类来代替listview。并且要22版本以上的,21版本不支持这个特性
compile ‘com.android.support:recyclerview-v7:22.2.1‘
然后xml文件要稍微更改一下
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:app="http://schemas.android.com/apk/res-auto" 3 xmlns:tools="http://schemas.android.com/tools" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent" 6 android:paddingBottom="@dimen/activity_vertical_margin" 7 android:paddingLeft="@dimen/activity_horizontal_margin" 8 android:paddingRight="@dimen/activity_horizontal_margin" 9 android:paddingTop="@dimen/activity_vertical_margin" 10 tools:context=".MainActivity"> 11 12 <android.support.design.widget.CoordinatorLayout 13 android:layout_width="match_parent" 14 android:layout_height="match_parent"> 15 16 <android.support.v7.widget.RecyclerView 17 android:id="@+id/recyclerView" 18 android:layout_width="match_parent" 19 android:layout_height="match_parent"> 20 21 </android.support.v7.widget.RecyclerView> 22 23 <android.support.design.widget.FloatingActionButton 24 android:layout_width="wrap_content" 25 android:layout_height="wrap_content" 26 android:layout_gravity="bottom|right" 27 android:layout_margin="16dp" 28 app:layout_anchor="@id/recyclerView" 29 app:layout_anchorGravity="bottom|right|end" 30 app:layout_behavior="com.example.administrator.testfab.ScrollBehavior" /> 31 </android.support.design.widget.CoordinatorLayout> 32 33 34 </RelativeLayout>
注意30行 使用了一个我们自定义的behavior。
1 package com.example.administrator.testfab; 2 3 4 import android.content.Context; 5 import android.os.Build; 6 import android.support.design.widget.CoordinatorLayout; 7 import android.support.design.widget.FloatingActionButton; 8 import android.support.v4.view.ViewCompat; 9 import android.support.v4.view.ViewPropertyAnimatorListener; 10 import android.support.v4.view.animation.FastOutSlowInInterpolator; 11 import android.util.AttributeSet; 12 import android.view.View; 13 import android.view.animation.Animation; 14 import android.view.animation.AnimationUtils; 15 import android.view.animation.Interpolator; 16 17 public class ScrollBehavior extends FloatingActionButton.Behavior { 18 private static final Interpolator INTERPOLATOR = new FastOutSlowInInterpolator(); 19 private boolean mIsAnimatingOut = false; 20 21 public ScrollBehavior(Context context, AttributeSet attrs) { 22 super(); 23 } 24 25 @Override 26 public boolean onStartNestedScroll(final CoordinatorLayout coordinatorLayout, final FloatingActionButton child, 27 final View directTargetChild, final View target, final int nestedScrollAxes) { 28 // 确定是在垂直方向上滑动 29 return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL 30 || super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes); 31 } 32 33 @Override 34 public void onNestedScroll(final CoordinatorLayout coordinatorLayout, final FloatingActionButton child, 35 final View target, final int dxConsumed, final int dyConsumed, 36 final int dxUnconsumed, final int dyUnconsumed) { 37 super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed); 38 if (dyConsumed > 0 && !this.mIsAnimatingOut && child.getVisibility() == View.VISIBLE) { 39 // 不显示FAB 40 animateOut(child); 41 } else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE) { 42 // 显示FAB 43 animateIn(child); 44 } 45 } 46 47 // 定义滑动时的属性动画效果 48 private void animateOut(final FloatingActionButton button) { 49 if (Build.VERSION.SDK_INT >= 14) { 50 ViewCompat.animate(button).scaleX(0.0F).scaleY(0.0F).alpha(0.0F).setInterpolator(INTERPOLATOR).withLayer() 51 .setListener(new ViewPropertyAnimatorListener() { 52 public void onAnimationStart(View view) { 53 ScrollBehavior.this.mIsAnimatingOut = true; 54 } 55 56 public void onAnimationCancel(View view) { 57 ScrollBehavior.this.mIsAnimatingOut = false; 58 } 59 60 public void onAnimationEnd(View view) { 61 ScrollBehavior.this.mIsAnimatingOut = false; 62 view.setVisibility(View.GONE); 63 } 64 }).start(); 65 } else { 66 Animation anim = AnimationUtils.loadAnimation(button.getContext(), R.anim.fab_out); 67 anim.setInterpolator(INTERPOLATOR); 68 anim.setDuration(200L); 69 anim.setAnimationListener(new Animation.AnimationListener() { 70 public void onAnimationStart(Animation animation) { 71 ScrollBehavior.this.mIsAnimatingOut = true; 72 } 73 74 public void onAnimationEnd(Animation animation) { 75 ScrollBehavior.this.mIsAnimatingOut = false; 76 button.setVisibility(View.GONE); 77 } 78 79 @Override 80 public void onAnimationRepeat(final Animation animation) { 81 } 82 }); 83 button.startAnimation(anim); 84 } 85 } 86 87 private void animateIn(FloatingActionButton button) { 88 button.setVisibility(View.VISIBLE); 89 if (Build.VERSION.SDK_INT >= 14) { 90 ViewCompat.animate(button).scaleX(1.0F).scaleY(1.0F).alpha(1.0F) 91 .setInterpolator(INTERPOLATOR).withLayer().setListener(null) 92 .start(); 93 } else { 94 Animation anim = AnimationUtils.loadAnimation(button.getContext(), R.anim.fab_in); 95 anim.setDuration(200L); 96 anim.setInterpolator(INTERPOLATOR); 97 button.startAnimation(anim); 98 } 99 } 100 }
最后看一下效果:
最后FAB的源码只有300行,继承自IMAGEVIEW,比较简单,我就不带大家分析了,但是这个源码还是建议去看一下,
因为FAB源码里面会有很多自定义属性的代码在里面,FAB在版本不同的android机器上面会有不一样的显示效果(其实就是小bug),
如果发现这类小bug,需要自己看下源码 找到对应的属性 然后自己把这个属性在外部定义成你想统一的效果才行!