zoukankan      html  css  js  c++  java
  • FloatingActionButton FAB 悬浮按钮

    概述

    浮动操作按钮 (简称 FAB) 是一个特殊的promoted(进阶)操作案例,因为一个浮动在UI之上的圆形图标而显得格外突出,同时它还具有动态的效果,比如变形、弹出、位移等。
    • 不是每个屏幕都需要浮动操作按钮,一个屏幕只推荐使用一个浮动操作按钮来增加其显著性,它应该只代表最常见的操作
    • 用浮动操作按钮进行积极的操作,如创建、收藏、分享、浏览和探索。避免用浮动操作按钮进行轻微破坏性操作。
    • 浮动操作按钮不包含 app 图标或状态栏通知。不要把证章或者其他元素层叠在浮动操作按钮上。
    • APP 主要操作的图案强制使用圆形图标。
    • 不要给浮动操作按钮额外的维度。
    • 在默认情况下,浮动操作按钮就像一块扩展的物体在屏幕上活动。在它里面的图标可能是活动的。

    ……里面列出了几十种使用规范,但是却没有一行代码

    基本使用

    继承关系
    1. public class FloatingActionButton extends VisibilityAwareImageButton
    2. class VisibilityAwareImageButton extends ImageButton
    放置浮动操作按钮需要使用CoordinatorLayout。CoordinatorLayout可以让一个元素浮动在另一个元素之上,还帮助我们协调它所包含的子view之间的交互,比如当用户往下滚动一个页面,浮动操作按钮应该消失,一旦向上滚动,则重现。
    另外,由于CoordinatorLayout不支持和ListView一起工作,所以需要用RecyclerView来替换ListViews。同时你还必须把RecyclerView升级到v22版本,之前的v21同样不支持与CoordinatorLayout一起工作。

    案例:
    1. <android.support.design.widget.FloatingActionButton
    2. android:layout_width="wrap_content"
    3. android:layout_height="wrap_content"
    4. android:layout_margin="16dp"
    5. app:backgroundTint="#00f"
    6. app:layout_anchor="@id/app_bar"
    7. app:layout_anchorGravity="bottom|end"
    8. app:layout_behavior="com.example.administrator.myapplication.ScrollAwareFABBehavior"
    9. app:srcCompat="@android:drawable/ic_dialog_email"/>
    其中:
    • app:backgroundTint:按钮的背景颜色,默认使用theme中colorAccent的颜色
    • app:layout_anchor:指定参照物
    • app:layout_anchorGravity:指定相对于参照物的位置
    • app:layout_behavior:设置FAB自定义显示隐藏动画效果
    • app:srcCompat或android:src:设置浮动按钮的图标
    其他相关属性:
    • app:fabSize:按钮是正常大小还是小号 Size for the FAB. 
    • app:rippleColor点击的边缘阴影颜色,默认取的是theme中的colorControlHighlight
    • app:useCompatPadding:是否启用 Enable compat padding. 
    • app:borderWidth:边框宽度。通常设置为0,同时设置一个合理的margin(16dp),可以解决Android 5.X设备上阴影无法正常显示的问题
    • app:elevation:和立体感相关的属性,设置边缘阴影的宽度 Elevation value for the FAB
    • app:pressedTranslationZ:和立体感相关的属性,设置点击按钮时,按钮边缘阴影的宽度,通常设置比elevation的数值大

    根据谷歌的设计规范,drawable的尺寸应该是24dp,按钮应该处于屏幕的右下角,margin设置为16dp。

    FAB与Snackbar

    当Snackbar在显示的时候,往往出现在屏幕的底部。为了给Snackbar留出空间,浮动操作按钮需要向上移动。
    只要使用CoordinatorLayout作为基本布局,将自动产生向上移动的动画。浮动操作按钮有一个 默认的 behavior 来检测Snackbar的添加并让按钮在Snackbar之上呈现上移与Snackbar等高的动画
    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. android:layout_width="match_parent"
    5. android:layout_height="match_parent"
    6. android:fitsSystemWindows="true">
    7. <android.support.v4.widget.NestedScrollView
    8. android:id="@+id/nsv"
    9. android:layout_width="match_parent"
    10. android:layout_height="match_parent"
    11. app:layout_behavior="@string/appbar_scrolling_view_behavior">
    12. <TextView
    13. android:layout_width="match_parent"
    14. android:layout_height="wrap_content"
    15. android:text="CoordinatorLayout NestedScrollView"
    16. android:textSize="30sp"/>
    17. </android.support.v4.widget.NestedScrollView>
    18. <android.support.design.widget.FloatingActionButton
    19. android:id="@+id/fab"
    20. android:layout_width="wrap_content"
    21. android:layout_height="wrap_content"
    22. android:layout_margin="16dp"
    23. app:backgroundTint="#00f"
    24. app:layout_anchor="@id/nsv"
    25. app:layout_anchorGravity="bottom|right|end"
    26. app:srcCompat="@android:drawable/ic_dialog_email"/>
    27. </android.support.design.widget.CoordinatorLayout>

    显示与隐藏动画

    FloatingActionButton的显示和隐藏有点让人困惑,可以找到多种实现方式,而且兼容包里的FloatingActionButton还不断的变化。
    基本来说,如果是使用官方的FloatingActionButton,列表滚动时的显示与隐藏都是使用自定义FloatingActionButton.Behavior来实现的。

    NestedScrollView默认app:layout_behavior为:
    1. app:layout_behavior="@string/appbar_scrolling_view_behavior"
    1. <string name="appbar_scrolling_view_behavior" translatable="false">android.support.design.widget.AppBarLayout$ScrollingViewBehavior</string>

    动画模板

    1. /**
    2. * Fab在滚动时候的显示与隐藏,直接借用了FloatingActionButton内置的动画效果,仅仅是在条件恰当的时候调用hide()和show()方法
    3. */
    4. public class ScrollAwareFABBehaviorDefault extends FloatingActionButton.Behavior {
    5. public ScrollAwareFABBehaviorDefault(Context context, AttributeSet attrs) {
    6. super();
    7. }
    8. @Override
    9. public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child,
    10. View directTargetChild, View target, int nestedScrollAxes) {
    11. // Ensure we react to vertical scrolling
    12. return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL
    13. || super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
    14. }
    15. @Override
    16. public void onNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child, View target,
    17. int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
    18. super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
    19. if (dyConsumed > 0 && child.getVisibility() == View.VISIBLE) {// User scrolled down and the FAB is currently visible
    20. child.hide();//如果要自定义动画效果,就在这里重新定义隐藏时的动画
    21. Snackbar.make(coordinatorLayout, "隐藏", Snackbar.LENGTH_SHORT).show();
    22. } else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE) {// User scrolled up and the FAB is currently not visible
    23. child.show();
    24. Snackbar.make(coordinatorLayout, "显示", Snackbar.LENGTH_SHORT).show();
    25. }
    26. }
    27. }

    自定义动画效果1

    1. /**
    2. * Fab在滚动时候的显示与隐藏,自定义上下滑动的动画
    3. */
    4. public class ScrollAwareFABBehavior extends FloatingActionButton.Behavior {
    5. private boolean mIsAnimatingOut = false;
    6. public ScrollAwareFABBehavior(Context context, AttributeSet attrs) {
    7. super();
    8. }
    9. @Override
    10. public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child,
    11. View directTargetChild, View target, int nestedScrollAxes) {
    12. // Ensure we react to vertical scrolling
    13. return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL
    14. || super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
    15. }
    16. @Override
    17. public void onNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child, View target,
    18. int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
    19. super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
    20. if (dyConsumed > 0 && child.getVisibility() == View.VISIBLE) {
    21. child.animate().scaleX(0.0F).scaleY(0.0F).alpha(0.0F).setDuration(1500).start();
    22. } else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE) {
    23. child.animate().scaleX(1.0F).scaleY(1.0F).alpha(1.0F).setDuration(1500).start();
    24. }
    25. }
    26. }

    自定义动画效果2

    1. /**
    2. * Fab在滚动时候的显示与隐藏,自定义上下滑动的动画
    3. */
    4. public class ScrollAwareFABBehavior extends FloatingActionButton.Behavior {
    5. private int toolbarHeight;
    6. public ScrollAwareFABBehavior(Context context, AttributeSet attrs) {
    7. super();
    8. this.toolbarHeight = getToolbarHeight(context);
    9. }
    10. @Override
    11. public boolean layoutDependsOn(CoordinatorLayout parent, FloatingActionButton fab, View dependency) {
    12. return super.layoutDependsOn(parent, fab, dependency) || (dependency instanceof AppBarLayout);
    13. }
    14. @Override
    15. public boolean onDependentViewChanged(CoordinatorLayout parent, FloatingActionButton fab, View dependency) {
    16. boolean returnValue = super.onDependentViewChanged(parent, fab, dependency);
    17. if (dependency instanceof AppBarLayout) {
    18. CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) fab.getLayoutParams();
    19. int fabBottomMargin = lp.bottomMargin;
    20. int distanceToScroll = fab.getHeight() + fabBottomMargin;
    21. float ratio = dependency.getY() / toolbarHeight;
    22. fab.setTranslationY(-distanceToScroll * ratio);
    23. }
    24. return returnValue;
    25. }
    26. public static int getToolbarHeight(Context context) {
    27. TypedArray styledAttributes = context.getTheme().obtainStyledAttributes(new int[]{R.attr.actionBarSize});
    28. int toolbarHeight = (int) styledAttributes.getDimension(0, 0);
    29. styledAttributes.recycle();
    30. return toolbarHeight;
    31. }
    32. }
    2017-5-23




  • 相关阅读:
    Java时间和时间戳的相互转换
    linux 通过pid 寻找程序路径的最简单命令(pwdx)
    Oracle--存储过程学习进阶
    经典sql总结(2)
    经典sql总结(1)
    类的初始化
    StringBuffer和String 的例子
    i=i++
    一个异常学习的好例子
    有空研究这篇http://blog.csdn.net/studyvcmfc/article/details/7720258 研究后写篇记录
  • 原文地址:https://www.cnblogs.com/baiqiantao/p/6890674.html
Copyright © 2011-2022 走看看