Это просто идея, что код можно улучшить. Вы можете изменить форму FloatingActionButton
с помощью атрибута shapeAppearanceOverlay
:
<com.google.android.material.floatingactionbutton.FloatingActionButton
app:shapeAppearanceOverlay="@style/cutfab"
..>
с помощью:
<style name="cutfab">
<item name="cornerFamily">cut</item>
<item name="cornerSize">15dp</item>
</style>
Затем вы можете определить BottomAppBar
в вашем макете:
<com.google.android.material.bottomappbar.BottomAppBar
android:id="@+id/bottomAppBar"
app:fabAlignmentMode="center"
app:fabCradleVerticalOffset="14dp"
app:fabCradleMargin="8dp" />
Наконец, вы можете подать заявку на BottomAppBar
a TopEdgeTreatment
. Примерно так:
BottomAppBar bar = findViewById(R.id.bar);
BottomAppBarTopEdgeTreatment topEdge = new BottomAppBarCutCornersTopEdge(
bar.getFabCradleMargin(),
bar.getFabCradleRoundedCornerRadius(),
bar.getCradleVerticalOffset());
MaterialShapeDrawable babBackground = (MaterialShapeDrawable) bar.getBackground();
babBackground.setShapeAppearanceModel(
babBackground.getShapeAppearanceModel()
.toBuilder()
.setTopEdge(topEdge)
.build());
введите описание изображения здесь
Где BottomAppBarCutCornersTopEdge
выглядит примерно так:
public class BottomAppBarCutCornersTopEdge extends BottomAppBarTopEdgeTreatment {
private final float fabMargin;
private final float cradleVerticalOffset;
BottomAppBarCutCornersTopEdge(
float fabMargin, float roundedCornerRadius, float cradleVerticalOffset) {
super(fabMargin, roundedCornerRadius, cradleVerticalOffset);
this.fabMargin = fabMargin;
this.cradleVerticalOffset = cradleVerticalOffset;
}
@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;
}
shapePath.lineTo(middle - (fabMargin + diamondSize), 0);
shapePath.lineTo(middle - fabDiameter/3, (diamondSize - cradleVerticalOffset + fabMargin) * interpolation);
shapePath.lineTo(middle + fabDiameter/3, (diamondSize - cradleVerticalOffset + fabMargin) * interpolation);
shapePath.lineTo(middle + (fabMargin + diamondSize), 0);
shapePath.lineTo(length, 0);
}
}
Чтобы получить лучший результат, вы должны расширить CutCornerTreatment
, реализовав в методе getCornerPath
тот же путь используется в BottomAppBar
и примените его к FloatingActionButton
.