简体   繁体   English

如何在 Flutter 中使用 CircularNotchedRectangle 向 BottomAppBar 添加圆角

[英]How to add rounded corners to BottomAppBar with CircularNotchedRectangle in Flutter

I want to create BottomAppBar with rounded corners, circular notched rectangle and material shadow.我想创建带有圆角、圆形缺口矩形和材质阴影的BottomAppBar The problem is that when I add rounded corners to BottomAppBar by wrapping it with ClipRRect widget I lose material shadow.问题是,当我通过用ClipRRect小部件包裹它向BottomAppBar添加圆角时,我失去了材质阴影。

BottomAppBar without rounded corners, but with Material shadow. BottomAppBar 没有圆角,但带有 Material 阴影。 Please ignore wrong aligned notch.请忽略错误对齐的缺口。 在此处输入图片说明

BottomAppBar wrapped in ClipRRect widget, but without shadow. BottomAppBar 包裹在 ClipRRect 小部件中,但没有阴影。 Again please ignore wrong aligned notch:再次请忽略错误对齐的缺口: 在此处输入图片说明

How to achieve rounded corners with notch and material shadow?如何用缺口和材质阴影实现圆角?

Full code:完整代码:

import 'package:flutter/material.dart';

void main() {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: Scaffold(
        extendBody: true,
        body: Container(
          color: Colors.amber,
        ),
        floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
        floatingActionButton: Transform.translate(
          offset: Offset(0, -10),
          child: FloatingActionButton(
            onPressed: () {},
            child: Icon(Icons.add),
            elevation: 2.0,
          ),
        ),
        bottomNavigationBar: BottomNavigationView(),
      ),
    );
  }
}

class BottomNavigationView extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Transform.translate(
      offset: Offset(0.0, -10),
      child: Container(
        margin: EdgeInsets.only(left: 20, right: 20),
        child: ClipRRect(
          borderRadius: BorderRadius.all(Radius.circular(30),
          ),
          child: BottomAppBar(
            shape: CircularNotchedRectangle(),
            child: Row(
              mainAxisSize: MainAxisSize.max,
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children: <Widget>[
                Column(
                  mainAxisSize: MainAxisSize.min,
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Icon(Icons.accessibility_new),
                  ],
                ),
                _buildMiddleTabItem(),
                Column(
                  mainAxisSize: MainAxisSize.min,
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Icon(Icons.accessibility_new),
                  ],
                )
              ],
            ),
          ),
        ),
      ),
    );
  }

  Widget _buildMiddleTabItem() {
    return Expanded(
      child: SizedBox(
        height: 60,
        child: Column(
          mainAxisSize: MainAxisSize.min,
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            SizedBox(height: 24),
            Text(''),
          ],
        ),
      ),
    );
  }
}

You can create your own ShapeBorder.您可以创建自己的 ShapeBorder。

在此处输入图片说明

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        extendBody: true,
        body: Container(
          color: Colors.amber,
        ),
        floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
        floatingActionButton: Transform.translate(
          offset: Offset(0, -10),
          child: FloatingActionButton(
            onPressed: () {},
            child: Icon(Icons.add),
            elevation: 2.0,
          ),
        ),
        bottomNavigationBar: BottomNavigationView(),
      ),
    );
  }
}

class BottomNavigationView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Transform.translate(
      offset: Offset(0.0, -10),
      child: Container(
        margin: EdgeInsets.symmetric(horizontal: 10),
        padding: EdgeInsets.symmetric(horizontal: 20),
        decoration: ShapeDecoration(
          color: Colors.white,
          shape: MyBorderShape(),
          shadows: [
            BoxShadow(
                color: Colors.black38, blurRadius: 8.0, offset: Offset(1, 1)),
          ],
        ),
        child: Row(
          mainAxisSize: MainAxisSize.max,
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: <Widget>[
            Column(
              mainAxisSize: MainAxisSize.min,
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Icon(Icons.accessibility_new),
              ],
            ),
            _buildMiddleTabItem(),
            Column(
              mainAxisSize: MainAxisSize.min,
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Icon(Icons.accessibility_new),
              ],
            )
          ],
        ),
      ),
    );
  }

  Widget _buildMiddleTabItem() {
    return Expanded(
      child: SizedBox(
        height: 60,
        child: Column(
          mainAxisSize: MainAxisSize.min,
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            SizedBox(height: 24),
            Text(''),
          ],
        ),
      ),
    );
  }
}

class MyBorderShape extends ShapeBorder {
  MyBorderShape();

  @override
  EdgeInsetsGeometry get dimensions => EdgeInsets.zero;

  @override
  Path getInnerPath(Rect rect, {TextDirection textDirection}) => null;

  double holeSize = 70;

  @override
  Path getOuterPath(Rect rect, {TextDirection textDirection}) {
    print(rect.height);
    return Path.combine(
      PathOperation.difference,
      Path()
        ..addRRect(
            RRect.fromRectAndRadius(rect, Radius.circular(rect.height / 2)))
        ..close(),
      Path()
        ..addOval(Rect.fromCenter(
            center: rect.center.translate(0, -rect.height / 2),
            height: holeSize,
            width: holeSize))
        ..close(),
    );
  }

  @override
  void paint(Canvas canvas, Rect rect, {TextDirection textDirection}) {}

  @override
  ShapeBorder scale(double t) => this;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM