查看: 1006|回复: 0

[手机开发] Android中Fab(FloatingActionButton)实现上下滑动的渐变效果

发表于 2017-8-1 08:00:04
尚学堂AD

前言

Promoted Actions是指一种操作按钮,它不是放在actionbar中,而是直接在可见的UI布局中(当然这里的UI指的是setContentView所管辖的范围)。因此它更容易在代码中被获取到(试想如果你要在actionbar中获取一个菜单按钮是不是很难?),Promoted Actions往往主要用于一个界面的主要操作,比如在email的邮件列表界面,promoted action可以用于接受一个新邮件。promoted action在外观上其实就是一个悬浮按钮,更常见的是漂浮在界面上的圆形按钮,一般我直接将promoted action称作悬浮按钮,英文名称Float Action Button 简称(FAB,不是FBI哈)。

系统自带的 Fab 也会随着页面上下滚动,但是淡出或者进入的效果太不自然。

这里记录一个小知识点,Fab 随着页面的 RecyclerView 上下滚动而渐变的动画效果。

包含 Fab 控件的布局如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. tools:context=".view.activity.MainActivity">
  8. <android.support.design.widget.AppBarLayout
  9. android:layout_width="match_parent"
  10. android:layout_height="wrap_content"
  11. android:theme="@style/AppTheme.AppBarOverlay">
  12. <android.support.v7.widget.Toolbar
  13. android:id="@+id/toolbar"
  14. android:layout_width="match_parent"
  15. android:layout_height="?attr/actionBarSize"
  16. android:background="?attr/colorPrimary"
  17. app:layout_scrollFlags="scroll|enterAlways"
  18. app:popupTheme="@style/AppTheme.PopupOverlay" />
  19. <android.support.design.widget.TabLayout
  20. android:id="@+id/tab_layout"
  21. app:tabIndicatorColor="#FFFFFF"
  22. android:layout_width="match_parent"
  23. android:layout_height="wrap_content">
  24. </android.support.design.widget.TabLayout>
  25. </android.support.design.widget.AppBarLayout>
  26. <include layout="@layout/content_main" />
  27. <android.support.design.widget.FloatingActionButton
  28. android:id="@+id/fab"
  29. android:layout_width="wrap_content"
  30. android:layout_height="wrap_content"
  31. android:layout_margin="@dimen/fab_margin"
  32. android:src="@android:drawable/ic_dialog_email"
  33. app:layout_behavior="com.wu.allen.zhuanlan.util.ScrollAwareFABBehavior"/>
  34. </android.support.design.widget.CoordinatorLayout>
复制代码

实现的 Java 代码如下:

  1. public class ScrollAwareFABBehavior extends FloatingActionButton.Behavior {
  2. private static final Interpolator INTERPOLATOR = new FastOutSlowInInterpolator();
  3. private boolean mIsAnimatingOut = false;
  4. public ScrollAwareFABBehavior(Context context, AttributeSet attrs) {
  5. super();
  6. }
  7. @Override
  8. public boolean onStartNestedScroll(final CoordinatorLayout coordinatorLayout, final FloatingActionButton child,
  9. final View directTargetChild, final View target, final int nestedScrollAxes) {
  10. // Ensure we react to vertical scrolling
  11. return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL
  12. || super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
  13. }
  14. @Override
  15. public void onNestedScroll(final CoordinatorLayout coordinatorLayout, final FloatingActionButton child,
  16. final View target, final int dxConsumed, final int dyConsumed,
  17. final int dxUnconsumed, final int dyUnconsumed) {
  18. super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
  19. if (dyConsumed > 0 && !this.mIsAnimatingOut && child.getVisibility() == View.VISIBLE) {
  20. // User scrolled down and the FAB is currently visible -> hide the FAB
  21. animateOut(child);
  22. } else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE) {
  23. // User scrolled up and the FAB is currently not visible -> show the FAB
  24. animateIn(child);
  25. }
  26. }
  27. // Same animation that FloatingActionButton.Behavior uses to hide the FAB when the AppBarLayout exits
  28. private void animateOut(final FloatingActionButton button) {
  29. if (Build.VERSION.SDK_INT >= 14) {
  30. ViewCompat.animate(button).scaleX(0.0F).scaleY(0.0F).alpha(0.0F).setInterpolator(INTERPOLATOR).withLayer()
  31. .setListener(new ViewPropertyAnimatorListener() {
  32. public void onAnimationStart(View view) {
  33. ScrollAwareFABBehavior.this.mIsAnimatingOut = true;
  34. }
  35. public void onAnimationCancel(View view) {
  36. ScrollAwareFABBehavior.this.mIsAnimatingOut = false;
  37. }
  38. public void onAnimationEnd(View view) {
  39. ScrollAwareFABBehavior.this.mIsAnimatingOut = false;
  40. view.setVisibility(View.GONE);
  41. }
  42. }).start();
  43. } else {
  44. Animation anim = AnimationUtils.loadAnimation(button.getContext(), R.anim.fab_out);
  45. anim.setInterpolator(INTERPOLATOR);
  46. anim.setDuration(200L);
  47. anim.setAnimationListener(new Animation.AnimationListener() {
  48. public void onAnimationStart(Animation animation) {
  49. ScrollAwareFABBehavior.this.mIsAnimatingOut = true;
  50. }
  51. public void onAnimationEnd(Animation animation) {
  52. ScrollAwareFABBehavior.this.mIsAnimatingOut = false;
  53. button.setVisibility(View.GONE);
  54. }
  55. @Override
  56. public void onAnimationRepeat(final Animation animation) {
  57. }
  58. });
  59. button.startAnimation(anim);
  60. }
  61. }
  62. // Same animation that FloatingActionButton.Behavior uses to show the FAB when the AppBarLayout enters
  63. private void animateIn(FloatingActionButton button) {
  64. button.setVisibility(View.VISIBLE);
  65. if (Build.VERSION.SDK_INT >= 14) {
  66. ViewCompat.animate(button).scaleX(1.0F).scaleY(1.0F).alpha(1.0F)
  67. .setInterpolator(INTERPOLATOR).withLayer().setListener(null)
  68. .start();
  69. } else {
  70. Animation anim = AnimationUtils.loadAnimation(button.getContext(), R.anim.fab_in);
  71. anim.setDuration(200L);
  72. anim.setInterpolator(INTERPOLATOR);
  73. button.startAnimation(anim);
  74. }
  75. }
  76. }
复制代码

fab_in.xml 文件如下(fab_out.xml 同理),当然要改变淡出或者进入的样式,一般修改这里的 XML 文件就可以了 :

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <set xmlns:android="http://schemas.android.com/apk/res/android">
  3. <alpha android:fromAlpha="0.0"
  4. android:toAlpha="1.0"/>
  5. <scale android:fromXScale="0.0"
  6. android:fromYScale="0.0"
  7. android:toXScale="1.0"
  8. android:toYScale="1.0"
  9. android:pivotX="50%"
  10. android:pivotY="50%"/>
  11. </set>
复制代码
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <set xmlns:android="http://schemas.android.com/apk/res/android">
  3. <alpha android:fromAlpha="1.0"
  4. android:toAlpha="0.0"/>
  5. <scale android:fromXScale="1.0"
  6. android:fromYScale="1.0"
  7. android:toXScale="0.0"
  8. android:toYScale="0.0"
  9. android:pivotX="50%"
  10. android:pivotY="50%"/>
  11. </set>
复制代码

大致效果就像上面。

总结

好了,以上就是这篇文章的全部内容了,希望本文的内容对各位android开发者们能带来一定的帮助,如果有疑问大家可以留言交流。



回复

使用道具 举报