如何使用fab风格的钻石?

时间:2019-01-06 21:46:45

标签: android material-design floating-action-button android-bottomappbar

如何在fab +底部应用栏上使用菱形样式? https://material.io/tools/theme-editor/网站上的草图文件中有以下样式fab: enter image description here

查看了所有可能的样式和标签...

2 个答案:

答案 0 :(得分:3)

BottomAppBar目前没有正式的形状。

不过,对于material components library 1.1.0 版本,您可以使用 app:shapeAppearance自定义shapeFloatingActionButton 属性。

您可以使用类似的内容:

 <com.google.android.material.floatingactionbutton.FloatingActionButton
        app:layout_anchor="@id/bar"
        app:shapeAppearance="@style/FabDiamondOverlay"
        .../>

具有这种样式:

 <style name="FabDiamondOverlay" parent="">
    <item name="cornerFamily">cut</item>
    <item name="cornerSize">8dp</item>
  </style>

它是结果:

enter image description here

当前,形状主题属性不会影响BottomAppBar,并且您只能为FAB通讯座设置圆角。官方存储库中添加了workaround

只需使用具有属性 app:fabCradleMargin 的默认BottomAppBar(它定义FloatingActionButtonBottomAppBar之间的距离)

<com.google.android.material.bottomappbar.BottomAppBar
        android:id="@+id/bar"
        ...
        android:layout_gravity="bottom"
        app:fabCradleMargin="10dp"
        />

并使用BottomAppBarTopEdgeTreatment更改BottomAppBar的形状:

    BottomAppBar bar = findViewById(R.id.bar);
    FloatingActionButton fab2 = findViewById(R.id.fab);
    BottomAppBarTopEdgeTreatment topEdge = new BottomAppBarCutCornersTopEdge(
            bar.getFabCradleMargin(),
            bar.getFabCradleRoundedCornerRadius(),
            bar.getCradleVerticalOffset());
    MaterialShapeDrawable babBackground = (MaterialShapeDrawable) bar.getBackground();
    //It requires 1.1.0-alpha10
    babBackground.setShapeAppearanceModel(
      babBackground.getShapeAppearanceModel()
      .toBuilder()
      .setTopEdge(topEdge)
      .build());

这是最终结果:

enter image description here

答案 1 :(得分:0)

加布里埃尔·马里奥蒂(Gabriele Mariotti)的道具。我使用了他的代码,并对其进行了一些更改,以使底部应用栏的外观变得圆润,就像原始问题一样。

首先,对于FAB,我将其圆角corners并旋转了45度,如下所示:

fab的XML代码:

<com.google.android.material.floatingactionbutton.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/fabHome"
        android:rotation="45"
        app:layout_anchor="@id/bottomBarHome"
        app:shapeAppearanceOverlay="@style/FabDiamondOverlay"/>

FabDiamondOverlay是:

<style name="FabDiamondOverlay" parent="">
    <item name="cornerFamily">rounded</item>
    <item name="cornerSize">15%</item>
</style>

给出最终的FAB:

Diamond rounded FAB

现在显示底部的XML:

<com.google.android.material.bottomappbar.BottomAppBar
        android:id="@+id/bottomBarHome"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:backgroundTint="@color/grey"
        app:fabCradleMargin="20dp"
        app:fabCradleVerticalOffset="5dp"
        android:layout_gravity="bottom" />

和OnCreate方法中的以下代码为底部的应用栏提供自定义外观:

    BottomAppBar bar = findViewById(R.id.bottomBarHome);

    BottomAppBarTopEdgeTreatment topEdge = new BottomAppBarCutCornersTopEdge(
            bar.getFabCradleMargin(),
            bar.getFabCradleRoundedCornerRadius(),
            bar.getCradleVerticalOffset());

    MaterialShapeDrawable bottomBarBackground = (MaterialShapeDrawable) bar.getBackground();
    bottomBarBackground.setShapeAppearanceModel(
            bottomBarBackground.getShapeAppearanceModel()
                    .toBuilder()
                    .setTopRightCorner(CornerFamily.ROUNDED,75)
                    .setTopLeftCorner(CornerFamily.ROUNDED,75)
                    .setTopEdge(topEdge)
                    .build());

BottomAppBarCutCornersTopEdge处通过修改加布里埃尔的代码: Source

@Override
    @SuppressWarnings("RestrictTo")
    public void getEdgePath(float length, float center, float interpolation, ShapePath shapePath) {
        float fabDiameter = getFabDiameter();
        if (fabDiameter == 0) {
            shapePath.lineTo(length, 0);
            return;
        }

        float diamondSize = fabDiameter / 2f;
        float middle = center + getHorizontalOffset();

        float verticalOffsetRatio = cradleVerticalOffset / diamondSize;
        if (verticalOffsetRatio >= 1.0f) {
            shapePath.lineTo(length, 0);
            return;
        }

        float barLeftVertex = middle - (fabMargin + diamondSize - cradleVerticalOffset);
        float barRightVertex = middle + (fabMargin + diamondSize - cradleVerticalOffset);
        float depth = (diamondSize - cradleVerticalOffset + fabMargin) * interpolation;

        float heightArc = 25;
        float widthArc = 25;

        shapePath.lineTo(barLeftVertex, 0);

        shapePath.lineTo(middle-widthArc, depth-heightArc);

        shapePath.addArc(middle-widthArc-10, 35, middle+widthArc+10, depth-15, 135, -83);

        shapePath.lineTo(middle+widthArc, depth-heightArc);
        shapePath.lineTo(barRightVertex, 0);

        shapePath.lineTo(length, 0);
    }

此处的值是由点击和尝试决定的。我不明白每个变量的作用,而且关于它的文档似乎很少。但这可以完成工作!这是最终结果:

Final image