|
import 'package:flutter/foundation.dart'; |
|
import 'package:flutter/material.dart'; |
|
|
|
void main() => runApp(MyApp()); |
|
|
|
class MyApp extends StatefulWidget { |
|
MyApp({Key key}) : super(key: key); |
|
State createState() => _MyAppState(); |
|
} |
|
|
|
class _MyAppState extends State<MyApp> { |
|
int _count = 0; |
|
|
|
@override |
|
Widget build(BuildContext context) { |
|
final title = 'Floating App Bar'; |
|
|
|
return MaterialApp( |
|
debugShowCheckedModeBanner: false, |
|
title: title, |
|
home: Scaffold( |
|
appBar: AppBar( |
|
title: Text('Sample Code'), |
|
), |
|
body: Center( |
|
child: Text('You have pressed the button $_count times.'), |
|
), |
|
bottomNavigationBar: BottomAppBar( |
|
child: Container( |
|
height: 50.0, |
|
), |
|
), |
|
floatingActionButton: FloatingActionButton( |
|
child: Icon(Icons.add), |
|
tooltip: 'Increment Counter', |
|
foregroundColor: Colors.red, |
|
backgroundColor: Colors.yellow, |
|
elevation: 20.0, |
|
onPressed: () => setState(() { |
|
_count++; |
|
}), |
|
mini: true, |
|
shape: |
|
SquircleBorder(side: BorderSide(width: 2.0, color: Colors.red)), |
|
), |
|
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, |
|
), |
|
); |
|
} |
|
} |
|
|
|
class SquircleBorder extends ShapeBorder { |
|
final BorderSide side; |
|
final double superRadius; |
|
|
|
const SquircleBorder({ |
|
this.side = BorderSide.none, |
|
this.superRadius = 5.0, |
|
}) : assert(side != null), |
|
assert(superRadius != null); |
|
|
|
@override |
|
EdgeInsetsGeometry get dimensions => EdgeInsets.all(side.width); |
|
|
|
@override |
|
ShapeBorder scale(double t) { |
|
return SquircleBorder( |
|
side: side.scale(t), |
|
superRadius: superRadius * t, |
|
); |
|
} |
|
|
|
@override |
|
Path getInnerPath(Rect rect, {TextDirection textDirection}) { |
|
return _squirclePath(rect.deflate(side.width), superRadius); |
|
} |
|
|
|
@override |
|
Path getOuterPath(Rect rect, {TextDirection textDirection}) { |
|
return _squirclePath(rect, superRadius); |
|
} |
|
|
|
static Path _squirclePath(Rect rect, double superRadius) { |
|
final c = rect.center; |
|
final dx = c.dx * (1.0 / superRadius); |
|
final dy = c.dy * (1.0 / superRadius); |
|
return new Path() |
|
..moveTo(c.dx, 0.0) |
|
..relativeCubicTo(c.dx - dx, 0.0, c.dx, dy, c.dx, c.dy) |
|
..relativeCubicTo(0.0, c.dy - dy, -dx, c.dy, -c.dx, c.dy) |
|
..relativeCubicTo(-(c.dx - dx), 0.0, -c.dx, -dy, -c.dx, -c.dy) |
|
..relativeCubicTo(0.0, -(c.dy - dy), dx, -c.dy, c.dx, -c.dy) |
|
..close(); |
|
} |
|
|
|
@override |
|
void paint(Canvas canvas, Rect rect, {TextDirection textDirection}) { |
|
switch (side.style) { |
|
case BorderStyle.none: |
|
break; |
|
case BorderStyle.solid: |
|
var path = getOuterPath(rect.deflate(side.width / 2.0), |
|
textDirection: textDirection); |
|
canvas.drawPath(path, side.toPaint()); |
|
} |
|
} |
|
} |