带支持库的 FloatingActionButton 示例

最近,我读到了这些帖子:

但是,他们都没有给我一个关于创建一个新的 FloatingActionButton的详细例子。这很难理解,所以我才问这个问题。

有人能给我举个例子吗?

剪辑

我只是发现了一些问题的 FloatingActionButton(FAB) ,我想改进另一个答案。见下面我的答案。

184872 次浏览

FloatingActionButton扩展了 ImageView。因此,这很简单,就像在布局中引入 ImageView一样。下面是一个 XML 示例。

<android.support.design.widget.FloatingActionButton   xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/somedrawable"
android:layout_gravity="right|bottom"
app:borderWidth="0dp"
app:rippleColor="#ffffff"/>

增加了 app:borderWidth="0dp"作为解决海拔问题的工作区。

因此,在 build.gradle文件中,添加以下内容:

compile 'com.android.support:design:27.1.1'

AndroidX 注意: Google 正在引入新的 AndroidX 扩展库来取代旧的支持库。要使用 AndroidX,首先确保 你更新了你的 gradle.properties文件,编辑 build.gradlecompileSdkVersion设置为 28(或更高) ,并使用以下代码行代替之前的 compile代码行。

implementation 'com.google.android.material:material:1.0.0'

接下来,在你的 themes.xml或者 styles.xml或者其他什么地方,确保你设置了这个——这是你的应用程序的重音颜色——以及 FAB 的颜色,除非你覆盖它(见下文) :

        <item name="colorAccent">@color/floating_action_button_color</item>

在布局的 XML 中:

<RelativeLayout
...
xmlns:app="http://schemas.android.com/apk/res-auto">


<android.support.design.widget.FloatingActionButton
android:id="@+id/myFAB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_plus_sign"
app:elevation="4dp"
... />


</RelativeLayout>

或者,如果你正在使用上面的 AndroidX 材料库,你可以使用以下代码:

<RelativeLayout
...
xmlns:app="http://schemas.android.com/apk/res-auto">


<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/myFAB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:srcCompat="@drawable/ic_plus_sign"
app:elevation="4dp"
... />


</RelativeLayout>

你可以在 医生 (材料文件在这里)(setRippleColor等)中看到更多的选项,但值得注意的是:

    app:fabSize="mini"

另一个有趣的方法是——只改变一个 FAB 的背景颜色,添加:

    app:backgroundTint="#FF0000"

(例如将其更改为红色)。

无论如何,在代码中,在 Activity/Fragment 的视图膨胀之后... ..。

    FloatingActionButton myFab = (FloatingActionButton)  myView.findViewById(R.id.myFAB);
myFab.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
doMyThing();
}
});

观察结果:

  • 如果你有一个这样的按钮,在一个“接缝”分开两个视图 (例如,使用 RelativeLayout) ,底部为负 布局边距与边框重叠时,你会注意到一个问题: FAB 的大小实际上是非常 与众不同对棒棒糖。 您可以在 AS 的可视化布局编辑器中看到这一点 当您在 API 之间切换时——当您切换到 额外大小的原因似乎是 阴影将视图的大小扩展到每个方向,因此你必须 当你调整 FAB 的利润时,如果它接近于其他利润,就要考虑到这一点 东西。
  • 这里有一个方法可以移除或者 如果填充物太多,就改变填充物:

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
    RelativeLayout.LayoutParams p = (RelativeLayout.LayoutParams) myFab.getLayoutParams();
    p.setMargins(0, 0, 0, 0); // get rid of margins since shadow area is now the margin
    myFab.setLayoutParams(p);
    }
    
  • Also, I was going to programmatically place the FAB on the "seam" between two areas in a RelativeLayout by grabbing the FAB's height, dividing by two, and using that as the margin offset. But myFab.getHeight() returned zero, even after the view was inflated, it seemed. Instead I used a ViewTreeObserver to get the height only after it's laid out and then set the position. See this tip here. It looked like this:

        ViewTreeObserver viewTreeObserver = closeButton.getViewTreeObserver();
    if (viewTreeObserver.isAlive()) {
    viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
    closeButton.getViewTreeObserver().removeGlobalOnLayoutListener(this);
    } else {
    closeButton.getViewTreeObserver().removeOnGlobalLayoutListener(this);
    }
    // not sure the above is equivalent, but that's beside the point for this example...
    RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) closeButton.getLayoutParams();
    params.setMargins(0, 0, 16, -closeButton.getHeight() / 2); // (int left, int top, int right, int bottom)
    closeButton.setLayoutParams(params);
    }
    });
    }
    

    不确定这是否是正确的方法,但似乎是有效的。

  • 似乎你可以使按钮的阴影空间变小 降低海拔。
  • 如果你想在“接缝”上使用 FAB,你可以使用 layout_anchorlayout_anchorGravity,这里有一个例子:

    <android.support.design.widget.FloatingActionButton
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    app:layout_anchor="@id/appbar"
    app:layout_anchorGravity="bottom|right|end"
    android:src="@drawable/ic_discuss"
    android:layout_margin="@dimen/fab_margin"
    android:clickable="true"/>
    

Remember that you can automatically have the button jump out of the way when a Snackbar comes up by wrapping it in a CoordinatorLayout.

More:

我只是发现了一些问题的 FAB 和我想提高另一个答案。


SetRippleColor 问题

因此,一旦你通过 setRippleColor以编程方式设置波纹颜色(按下 FAB 颜色) ,问题就会出现。但是,我们仍然有另一种方法来设置它,即调用:

FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
ColorStateList rippleColor = ContextCompat.getColorStateList(context, R.color.fab_ripple_color);
fab.setBackgroundTintList(rippleColor);

你的项目需要有这样的结构:

/res/color/fab_ripple_color.xml

enter image description here

fab_ripple_color.xml的密码是:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:color="@color/fab_color_pressed" />
<item android:state_focused="true" android:color="@color/fab_color_pressed" />
<item android:color="@color/fab_color_normal"/>
</selector>

最后,稍微改变一下你的 FAB:

<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_action_add"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
app:fabSize="normal"
app:borderWidth="0dp"
app:elevation="6dp"
app:pressedTranslationZ="12dp"
app:rippleColor="@android:color/transparent"/> <!-- set to transparent color -->

对于 API 等级21及以上,设置右下边距为24dp:

...
android:layout_marginRight="24dp"
android:layout_marginBottom="24dp" />

浮动按钮设计指南

正如您在上面的 FAB xml 代码中看到的,我设置:

        ...
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
app:elevation="6dp"
app:pressedTranslationZ="12dp"
...
  • 通过设置这些属性,您不需要再次设置 layout_marginToplayout_marginRight(仅在棒棒糖之前)。安卓系统会自动将它放置在屏幕的右边,就像正常的 FAB Android Lollipop 一样。

        android:layout_alignParentBottom="true"
    android:layout_alignParentRight="true"
    

Or, you can use this in CoordinatorLayout:

        android:layout_gravity="end|bottom"
  • 根据来自谷歌的 这本指南的说法,你需要有6分贝的 elevation和12分贝的 pressedTranslationZ

FAB rules

对于 AndroidX 来说

<com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/ic_add" />

如果您已经添加了所有库,但它仍然不能工作 用途:

<com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/ic_add"
/>

而不是:

<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/ic_add"
/>

一切都会好起来的:)