我已经用ShapeBorder做了一个样板,你可以复制(粘贴到dartPad上,然后玩.用图像替换图标。
PS.我在DartPad中添加了一个LayoutBuilder。我添加了一个LayoutBuilder,让它更健壮的响应式布局。
这就是结果,希望能帮到你。
import "package:flutter/material.dart";
import "dart:math";
void main() {
runApp(MaterialApp(
debugShowCheckedModeBanner: false, home: Scaffold(body: HomeScreen())));
}
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
width: 300,
height: 800,
child: Column(children: <Widget>[
MyCustomCard(),
MyCustomCard(),
]));
}
}
class MyCustomCard extends StatelessWidget {
@override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (_, BoxConstraints bc) {
return Container(
padding: EdgeInsets.all(10),
color: Colors.black,
child: Stack(children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 80,
),
Container(
width: double.infinity,
//height: 400,
decoration: ShapeDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [Color(0xff3344ff), Color(0x883344ff)],
stops: [0, 1],
),
shape: CustomCardShape(
//kW:MediaQuery.of(context).size.width-40,
),
),
child: Padding(
padding: EdgeInsets.all(20),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(height: 20),
Text(
"Steve Jobs",
style: TextStyle(
color: Colors.white,
fontSize: 14,
fontWeight: FontWeight.bold,
),
),
Text(
"Seattle",
style:
TextStyle(color: Colors.white, fontSize: 18),
),
SizedBox(height: 20),
Text(
"hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello ",
style:
TextStyle(color: Colors.white, fontSize: 14),
),
]),
)),
]),
Positioned(
top: 20,
//left: (MediaQuery.of(context).size.width/2)-60, //100,
left: bc.constrainWidth() / 2 - 50,
child: Container(
alignment: Alignment.center,
width: 80,
decoration: BoxDecoration(
color: Colors.black,
shape: BoxShape.circle,
),
child: Icon(Icons.home, color: Colors.white, size: 80),
),
),
]), // stack
);
});
}
}
class CustomCardShape extends ShapeBorder {
//final double kH = 350; // card height
//final double kW; // = 260; // card width
final double circleW = 100;
CustomCardShape(); //{this.kW});
@override
EdgeInsetsGeometry get dimensions => EdgeInsets.all(0);
@override
Path getInnerPath(Rect rect, {TextDirection textDirection}) => null;
@override
Path getOuterPath(Rect rect, {TextDirection textDirection}) {
rect = Rect.fromPoints(rect.topLeft, rect.bottomRight);
double kW = rect.width - 20;
double kH = rect.height;
double www = (kW - circleW - 20) / 2;
double wwwR = www;
return Path()
..moveTo(rect.topLeft.dx, rect.topLeft.dy + 20)
..lineTo(rect.topLeft.dx, rect.topLeft.dy + kH)
// rect bottom left
..arcTo(Rect.fromLTWH(rect.topLeft.dx, rect.topLeft.dy + kH, 20, 20), -pi,
-pi / 2, false)
..lineTo(rect.topLeft.dx + kW, rect.topLeft.dy + kH + 20)
// rect bottom right
..arcTo(Rect.fromLTWH(rect.topLeft.dx + kW, rect.topLeft.dy + kH, 20, 20),
-3 * pi / 2, -pi / 2, false)
..lineTo(rect.topLeft.dx + kW + 20, rect.topLeft.dy + 20)
// rect top right
..arcTo(Rect.fromLTWH(rect.topLeft.dx + kW, rect.topLeft.dy, 20, 20), 0,
-pi / 2, false)
..lineTo(rect.topLeft.dx + kW - www, rect.topLeft.dy)
// circle bottom right
..arcTo(
Rect.fromLTWH(
rect.topLeft.dx + kW - wwwR, rect.topLeft.dy - 20, 20, 20),
pi / 2,
pi / 2,
false)
..lineTo(rect.topLeft.dx + kW - wwwR, rect.topLeft.dy - 20)
// circle
..arcTo(
Rect.fromLTWH(rect.topLeft.dx + kW - wwwR - circleW,
rect.topLeft.dy - 20 - 50, circleW, circleW),
0,
-pi,
false)
..lineTo(rect.topLeft.dx + kW - wwwR - circleW, rect.topLeft.dy - 20)
// circle bottom left
..arcTo(
Rect.fromLTWH(
rect.topLeft.dx + 20 + www - 20, rect.topLeft.dy - 20, 20, 20),
0,
pi / 2,
false)
..lineTo(rect.topLeft.dx, rect.topLeft.dy)
// rect top left
..arcTo(Rect.fromLTWH(rect.topLeft.dx, rect.topLeft.dy, 20, 20), -pi / 2,
-pi / 2, false)
..close();
}
@override
void paint(Canvas canvas, Rect rect, {TextDirection textDirection}) {}
@override
ShapeBorder scale(double t) => this;
}