动画一个Android浮动动作按钮

Valdio Veliu
分享

自材质设计引入以来,浮动动作按钮(FAB)已经成为实现最简单的组件之一,成为设计师和开发人员的快速和基本最爱。

在本教程中,我将向您展示如何使您的应用程序FAB互动,以及如何制作自己的动画。但让我们从简单的开始,添加浮动动作按钮到Android项目。

浮动动作按钮在布局文件中看起来像这样,如果创建一个Android Studio项目使用空白的活动

创建一个项目"loading=

<android.support.design.widget.FloatingActionButtonandroid:id@ + id /工厂android:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_gravity底|结束android:layout_margin@dimen / fab_marginandroid:src@android:可拉的/ ic_menu_help/>

浮动动作按钮

浮动操作按钮有两种大小。默认值是56dp,最小值是40dp。关于使用FAB的设计原则的进一步讨论,我建议您阅读谷歌的官方指南

在最近的Android应用中,FAB会对元素列表的滚动做出反应,在我看来,在滚动时应该隐藏FAB。我的意思是:

滚动时隐藏Fab"loading=

为了显示这个动画,我创建了一个recyclerView这样FAB就可以对滚动做出反应。

有很多库可以在1或2行代码中帮助实现这一目标,但对于那些好奇的人来说,这里有一个例子:

公共FAB_Hide_on_Scroll扩展FloatingActionButton行为公共FAB_Hide_on_Scroll上下文上下文AttributeSetattrs超级@Override公共无效onNestedScrollCoordinatorLayoutcoordinatorLayoutFloatingActionButton孩子视图目标intdxConsumedintdyConsumedintdxUnconsumedintdyUnconsumed超级onNestedScrollcoordinatorLayout孩子目标dxConsumeddyConsumeddxUnconsumeddyUnconsumed//child ->浮动动作按钮如果孩子getVisibility= =视图可见& &dyConsumed>0孩子隐藏其他的如果孩子getVisibility= =视图走了& &dyConsumed<0孩子显示@Override公共布尔onStartNestedScrollCoordinatorLayoutcoordinatorLayoutFloatingActionButton孩子视图directTargetChild视图目标intnestedScrollAxes返回nestedScrollAxes= =ViewCompatSCROLL_AXIS_VERTICAL

我用的是FloatingActionButton.Behavior ()类,根据官方文件,其主要功能是移动FloatingActionButton视图,以便显示任何间小吃店不要覆盖它们。但是在我们的例子中,这个类被扩展了,这样我们就可以实现我们自己的行为。

让我们更详细地了解这个行为类。它的意图是每当开始滚动时,onStartNestedScroll ()方法将返回真正的如果滚动是垂直的,从那里onNestedScroll ()方法将隐藏或显示浮动操作按钮,这取决于它当前的可见状态。

该类的构造函数是该视图行为的重要组成部分,它使该视图从XML文件中扩展

公共FAB_Hide_on_Scroll上下文上下文AttributeSetattrs超级

要使用此行为,请添加layout_behavior属性为浮动操作按钮。该属性包含包名,加上末尾的类名,或者换种说法,该类在项目中的确切位置。在我的例子中,它看起来是这样的:

应用:layout_behavior = " com.valdio.valdioveliu.floatingactionbuttonproject.Scrolling_Floating_Action_Button.FAB_Hide_on_Scroll "

这个动画看起来很酷,但它可以更好。我个人更喜欢在滚动应用内容时将FAB悬浮在屏幕外,这样更真实。我的意思是:

浮动工厂"loading=

应用了与前面相同的逻辑,只是FAB隐藏更改的方式不同。

动画很简单。FAB在屏幕上垂直漂浮LinearInterpolator.FAB向下浮动一段距离,计算其高度和底边距,以将其完全移出屏幕,并在向上滚动时浮动回其原始位置。

如果您仔细查看代码,会发现我删除了视图。可见视图。走了检查如果语句,因为视图在这里没有隐藏,只是浮在屏幕外。

公共FAB_Float_on_Scroll扩展FloatingActionButton行为公共FAB_Float_on_Scroll上下文上下文AttributeSetattrs超级@Override公共无效onNestedScrollCoordinatorLayoutcoordinatorLayoutFloatingActionButton孩子视图目标intdxConsumedintdyConsumedintdxUnconsumedintdyUnconsumed超级onNestedScrollcoordinatorLayout孩子目标dxConsumeddyConsumeddxUnconsumeddyUnconsumed//child ->浮动动作按钮如果dyConsumed>0CoordinatorLayoutLayoutParamslayoutParamsCoordinatorLayoutLayoutParams孩子getLayoutParamsintfab_bottomMarginlayoutParams页下空白孩子动画translationY孩子获得+fab_bottomMarginsetInterpolatorLinearInterpolator开始其他的如果dyConsumed<0孩子动画translationY0setInterpolatorLinearInterpolator开始@Override公共布尔onStartNestedScrollCoordinatorLayoutcoordinatorLayoutFloatingActionButton孩子视图directTargetChild视图目标intnestedScrollAxes返回nestedScrollAxes= =ViewCompatSCROLL_AXIS_VERTICAL

制作一个浮动操作按钮菜单

我见过许多Android应用程序制作了令人印象深刻的浮动操作按钮菜单,它们看起来和运行起来都很好。这里有一个例子:

工厂菜单"loading=

现在你已经知道我们要做什么了,让我们开始制作吧。

构建这个菜单的第一步是包含3个小按钮的布局。

所有的小按钮都是不可见的,位于布局的底部,在主FAB的下面。

内部fab_layout.xml

<FrameLayoutxmlns:安卓http://schemas.android.com/apk/res/androidxmlns:应用程序http://schemas.android.com/apk/res-autoandroid:layout_widthmatch_parentandroid:layout_heightmatch_parent><android.support.design.widget.FloatingActionButtonandroid:id@ + id / fab_1android:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_gravity底|结束android:layout_margin@dimen / fab_marginandroid:src@android:可拉的/ ic_menu_compassandroid:可见性看不见的应用:backgroundTint@color / colorFAB应用:fabSize迷你/><android.support.design.widget.FloatingActionButtonandroid:id@ + id / fab_2android:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_gravity底|结束android:layout_margin@dimen / fab_marginandroid:src@android:可拉的/ ic_menu_myplacesandroid:可见性看不见的应用:backgroundTint@color / colorFAB应用:fabSize迷你/><android.support.design.widget.FloatingActionButtonandroid:id@ + id / fab_3android:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_gravity底|结束android:layout_margin@dimen / fab_marginandroid:src@android:可拉的/ ic_menu_shareandroid:可见性看不见的应用:backgroundTint@color / colorFAB应用:fabSize迷你/>FrameLayout>

将此布局包含在活动的布局中,位于主FAB之下。

<包括布局@layout / fab_layout/>

现在布局已经设置好了,下一步是制作动画来显示和隐藏每个小fab。

谨慎!

在创建这些动画时,我遇到了触摸事件和小型fab的问题。当动画结束时,小fab的实际位置不会改变,只有视图出现在新位置,所以你不能在正确的位置上执行触摸事件。我解决这个问题的方法是将每个FAB的布局参数设置为其新位置,然后执行将视图拉到新位置的动画。

在本教程的其余部分,我将展示一个小型fab的动画制作过程。其他的过程是相同的,但是有不同的重定位参数。

显示浮动动作按钮菜单

FrameLayoutLayoutParamslayoutParamsFrameLayoutLayoutParamsfab1getLayoutParamslayoutParamsrightMargin+ =intfab1getWidth1.7layoutParams页下空白+ =intfab1获得0.25fab1setLayoutParamslayoutParamsfab1startAnimationshow_fab_1fab1setClickable真正的

我在这里重新定位fab1通过添加右页边距和下页边距layoutParams然后开始动画。

隐藏浮动动作按钮菜单

FrameLayoutLayoutParamslayoutParamsFrameLayoutLayoutParamsfab1getLayoutParamslayoutParamsrightMargin- =intfab1getWidth1.7layoutParams页下空白- =intfab1获得0.25fab1setLayoutParamslayoutParamsfab1startAnimationhide_fab_1fab1setClickable

隐藏的过程与前面的动画相反。

在这个FAB上使用的动画是:

/ /动画动画show_fab_1AnimationUtilsloadAnimationgetApplicationR动物fab1_show动画hide_fab_1AnimationUtilsloadAnimationgetApplicationR动物fab1_hide

现在剩下的就是动画了。在res /动物/文件夹中我为所有动画创建了文件。这些内容并不多,但是如果您需要帮助来理解每个标记或属性的作用,请阅读官方文档文档

内部fab1_show.xml

<?XML版本="1.0"编码="utf-8"?><xmlns:安卓http://schemas.android.com/apk/res/androidandroid:fillAfter真正的><!——旋转——><旋转android:持续时间500android:fromDegrees30.android:插入器@android:动画/ linear_interpolatorandroid:pivotX50%android:pivotY50%android:repeatCount4android:repeatMode反向android:toDegrees0>旋转><!-移动- ><翻译android:持续时间1000android:fromXDelta170%android:fromYDelta25%android:插入器@android:动画/ linear_interpolatorandroid:toXDelta0%android:toYDelta0%>翻译><!——淡入><αandroid:持续时间2000android:fromAlpha0.0android:插入器@android:动画/ decelerate_interpolatorandroid:toAlpha1.0>α>>

内部fab1_hide.xml

<?XML版本="1.0"编码="utf-8"?><xmlns:安卓http://schemas.android.com/apk/res/androidandroid:fillAfter真正的><!-移动- ><翻译android:持续时间1000android:fromXDelta-170%android:fromYDelta-25%android:插入器@android:动画/ linear_interpolatorandroid:toXDelta0%android:toYDelta0%>翻译><!——淡出><αandroid:持续时间2000android:fromAlpha1.0android:插入器@android:动画/ accelerate_interpolatorandroid:toAlpha0.0>α>>

最后,如果您查看负责移动视图的翻译标记,我重新定位FAB的因子(170%和25%)对应于java代码中添加和减去的边距因子。

相同的流程适用于其他两个晶圆厂,但重新定位系数为(150%和150%)fab2和(25%和170%)fab3

最终的项目是这样的:

最终项目"loading=

一个新的圆形动画

如果你想用fab制作一些特殊的动画,你可以使用ViewAnimationUtils类来在视图上显示动画。

本文的其余部分将特别关注这个类以及如何用它构建显示动画。不幸的是,这个类仅适用于API版本21 (LOLLIPOP)及更高版本。

创建一个新活动

由于本文代码示例的其余部分与前面的示例分离,所以我使用了一个新的Activity。如果您决定继续,请创建一个名为RevealActivity.确保这个活动的布局文件有一个浮动动作按钮,因为我们将利用它来启动动画。在我的例子中,FAB有android: id =“@ + id /工厂”

构建Reveal UI

要在视图上显示动画,你需要在动画执行后显示一个布局。

布局取决于你想在应用程序中显示的视图,但为了保持简单,我构建了一个“动画显示”的示例布局。

在布局文件夹中创建一个新文件,fab_reveal_layout.xml并插入以下代码。

<?XML版本="1.0"编码="utf-8"?><LinearLayoutxmlns:安卓http://schemas.android.com/apk/res/androidxmlns:应用程序http://schemas.android.com/apk/res-autoandroid:layout_widthmatch_parentandroid:layout_heightmatch_parentandroid:id@ + id / fabContainerLayoutandroid:layout_gravitycenter_vertical | center_horizontalandroid:背景@color / colorPrimaryandroid:重力中心android:可见性走了android:取向水平><FrameLayoutandroid:layout_widthwrap_contentandroid:layout_heightwrap_content><android.support.design.widget.FloatingActionButtonandroid:id@ + id / f2android:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_marginLeft@dimen / fab_marginandroid:layout_marginRight@dimen / fab_marginandroid:src@android:可拉的/ ic_dialog_email应用:backgroundTint@color / colorFAB/><TextViewandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_gravity正确的android:海拔高度8 dpandroid:文本Fab2android:输入textColor# fff/>FrameLayout><LinearLayoutandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:取向垂直><FrameLayoutandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_marginBottom@dimen / fab_marginandroid:layout_marginTop@dimen / fab_margin><android.support.design.widget.FloatingActionButtonxmlns:应用程序http://schemas.android.com/apk/res-autoandroid:id@ + id / f1android:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_marginLeft@dimen / fab_marginandroid:layout_marginRight@dimen / fab_marginandroid:海拔高度0 dpandroid:src@android:可拉的/ ic_dialog_map应用:backgroundTint@color / colorFAB应用:borderWidth0 dp应用:fabSize正常的/><TextViewandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_gravity正确的android:海拔高度8 dpandroid:文本Fab1android:输入textColor# fff/>FrameLayout><FrameLayoutandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_marginBottom@dimen / fab_marginandroid:layout_marginTop@dimen / fab_margin><android.support.design.widget.FloatingActionButtonandroid:id@ + id / f4android:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_marginLeft@dimen / fab_marginandroid:layout_marginRight@dimen / fab_marginandroid:src@android:可拉的/ ic_dialog_alert应用:backgroundTint@color / colorFAB/><TextViewandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_gravity正确的android:海拔高度8 dpandroid:文本Fab4android:输入textColor# fff/>FrameLayout>LinearLayout><FrameLayoutandroid:layout_widthwrap_contentandroid:layout_heightwrap_content><android.support.design.widget.FloatingActionButtonandroid:id@ + id / f3android:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_marginLeft@dimen / fab_marginandroid:layout_marginRight@dimen / fab_marginandroid:src@android:可拉的/ ic_dialog_dialer应用:backgroundTint@color / colorFAB/><TextViewandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_gravity正确的android:海拔高度8 dpandroid:文本Fab3android:输入textColor# fff/>FrameLayout>LinearLayout>

实际上,容器LinearLayout在这个文件中有一个可见性属性可见性= "了"因此,当您在文件中插入这段代码时,什么也看不见。控件中的可见性属性可检出此布局LinearLayout或者看看下面的图片。

布局视图"loading=

创建此文件后,将其包含在活动的布局文件中。

activity_reveal.xml

<?XML版本="1.0"编码="utf-8"?> / /……<包括布局@layout / content_reveal/><包括布局@layout / fab_reveal_layout/><android.support.design.widget.FloatingActionButtonandroid:id@ + id /工厂android:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_gravity底|结束android:layout_margin@dimen / fab_marginandroid:src@drawable / ic_add/>android.support.design.widget.CoordinatorLayout>

设置的RevealActivity

在Activity的布局中包含fab布局后,我们需要设置CircularReveal动画。

RevealActivity类创建以下浮动动作按钮的全局实例布尔来跟踪动画状态和fab_reveal_layout容器的布局。

私人LinearLayoutfabContainer私人FloatingActionButton工厂私人布尔fabMenuOpen

接下来,在RevealActivityonCreate ()方法来查找FAB的视图引用并添加一个点击监听器。我只启动了活动的FAB,因为这是启动动画所需要的。

@Override受保护的无效onCreatesavedInstanceState超级onCreatesavedInstanceState/ /……fabContainerLinearLayoutfindViewByIdRidfabContainerLayout工厂FloatingActionButtonfindViewByIdRid工厂工厂setOnClickListener视图OnClickListener@Override公共无效onClick视图视图toggleFabMenu

toggleFabMenu ()函数用于创建和启动显示动画。中添加以下代码即可RevealActivity类,我会详细描述它的功能。

@TargetApi构建VERSION_CODES棒棒糖私人无效toggleFabMenu如果fabMenuOpen工厂setImageResourceR可拉的ic_closeintcenterXfabContainergetWidth/2intcenterYfabContainer获得/2intstartRadius0intendRadiusint数学函数的fabContainergetWidthfabContainer获得/2fabContainersetVisibility视图可见ViewAnimationUtilscreateCircularRevealfabContainercenterXcenterYstartRadiusendRadiussetDuration1000开始其他的工厂setImageResourceR可拉的ic_addintcenterXfabContainergetWidth/2intcenterYfabContainer获得/2intstartRadiusint数学函数的fabContainergetWidthfabContainer获得/2intendRadius0动画师动画师ViewAnimationUtilscreateCircularRevealfabContainercenterXcenterYstartRadiusendRadius动画师setDuration1000动画师addListener动画师AnimatorListener@Override公共无效onAnimationStart动画师动画@Override公共无效onAnimationEnd动画师动画fabContainersetVisibility视图走了@Override公共无效onAnimationCancel动画师动画@Override公共无效onAnimationRepeat动画师动画动画师开始fabMenuOpenfabMenuOpen

正如我之前提到的createCircularReveal ()方法只适用于LOLLIPOP和更新的Android版本,所以这个函数有一个TargetApi为构建版本棒棒糖。这意味着当在一个预棒棒糖设备中启动时,这个函数将不会被调用。

这个函数做的第一件事是检查动画视图是否可见fabMenuOpen布尔值。

在这个函数中,我改变了工厂使用setImageResource()方法。类中添加此函数时,请确保将缺少的图像添加到可拉的文件夹,或者从函数中注释掉这行代码。

如果您现在运行项目,它将正常工作,如下面的GIF所示,但如果您有兴趣了解如何createCircularReveal ()请查看本文的下一节。

循环显示"loading=

ViewAnimationUtils.createCircularReveal ()方法

createCircularReveal ()方法用于设置动画。它接受五个参数,基于它们在视图上创建动画。

第一个参数是对将由动画圈显示的视图的引用。
接下来的两个参数是动画开始时屏幕的X坐标和Y坐标。这些坐标与显示动画的视图相关。

因为动画是一个圆,它需要它正在绘制的圆的半径,所以接下来的两个参数是动画的开始半径和结束半径。

关于本文的示例,如GIF所示,动画将从视图的中心开始,起始半径为“0”,结束半径由Math.hypot ()方法。要反转动画,只需改变开始和结束半径的值。

循环显示动画的棘手部分是找到与显示动画的视图相关的动画开始。

例如,我计算了动画的X坐标和Y坐标,分别是视图的宽度/2和高度/2,以便找到视图的中心来开始动画。

看看下面的图片,找出如何确定你自己的动画的坐标。

动画坐标"loading=

接下来是什么?

我希望我已经给了你一个如何在你自己的项目中动画浮动动作按钮的想法。从这里你应该阅读Android的动画资源为你的应用程序创建你自己的动画。你可以在上面找到这个项目的最终代码GitHub欢迎大家提出任何问题或评论。

Android操作栏提供更好的用户界面"></a>
         <div class= Android操作栏提供更好的用户界面 乔伊斯Echessa
jQuery浮动菜单和消息插件"></a>
         <div class= jQuery浮动菜单和消息插件 山姆-迪尔岭
开始Android:安装Android平台"></a>
         <div class= 开始Android:安装Android平台 杰夫·弗瑞森
jQuery浮动书签地球仪-非常有趣!"></a>
         <div class= jQuery浮动书签地球仪-非常有趣! 山姆-迪尔岭
Baidu