Flutter:卡片布局,卡片顶部有中心圆圈
Flutter: Card layout with centered circle on top of card
我对 flutter 还很陌生,我正在尝试制作一张包含两个部分的卡片,每个部分占 space 的一半。然后我想要一个位于卡片中心顶部的头像圆圈图像小部件,如图所示。
目前代码如下所示(包括两部分):
@override
Widget build(BuildContext context) {
// it enable scrolling on small device
return Center(
child: Card(
margin: const EdgeInsets.all(10.0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
color: cardColor,
child: Flex(
direction: Axis.vertical,
children: [
Expanded(
child: ClipRRect(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16)),
child: Container(
child: Image.asset("assets/images/card_background.jpg",
fit: BoxFit.fill),
)),
),
Expanded(
child: Column(
children: [
Container(
child: Text("Test"),
)
],
),
)
],
),
),
);
}
因此,我想知道如何才能让头像图像如图所示定位。或者如果我现在拥有的代码甚至有可能。在那种情况下,我想知道我应该使用哪些小部件来解决这个问题。
感谢您的帮助!
如果我没理解错的话,你想要一个 Card
的背景图片和一个位于顶部中央的 CircleAvatar
小部件。
您可以像这样使用 Stack
来做到这一点:
Card(
margin: const EdgeInsets.all(10),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
clipBehavior: Clip.antiAlias,
color: cardColor,
child: Stack(
children: [
Positioned.fill(
child: Image.asset(
'assets/images/card_background.jpg',
fit: BoxFit.fill,
),
),
const Positioned.fill(
child: Align(
alignment: Alignment.topCenter
child: CircleAvatar(
backgroundColor: Colors.orangeAccent,
),
),
)
],
)
),
你走在正确的轨道上,有一个Column
(或Flex
)和2个Expanded
来平分它。您只需要另一个 Stack
小部件来覆盖顶部的圆圈。您可以用 Align
小部件包裹圆圈并将其设置为对齐 center-left.
代码看起来像这样:
Stack
Column
- Expanded
- Expanded
Align
- Circle
没有什么是一个简单的 Stack 小部件无法解决的。
@override
Widget build(BuildContext context) {
// it enable scrolling on small device
return Center(
child: Card(
margin: const EdgeInsets.all(10.0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
color: Colors.blue,
child: Stack(
children: [
Flex(
direction: Axis.vertical,
children: [
Expanded(
child: ClipRRect(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16)),
child: Container(
color: Colors.red,
)),
),
Expanded(
child: Column(
children: [
Container(
child: Text("Test"),
)
],
),
)
],
),
// align a circle center and left, with a left margin
Align(
alignment: Alignment.centerLeft,
child: Container(
margin: const EdgeInsets.only(left: 20),
child: ClipOval(
child: Container(
width: 80,
height: 80,
color: Colors.black
)
)
)
)
]
),
),
);
}
您可以使用 Stack
小部件将小部件放置在其他小部件之上。
试试这个代码
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Stack(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
Expanded(
child: Container(
decoration: const BoxDecoration(
borderRadius: BorderRadius.only(topLeft: Radius.circular(10),topRight: Radius.circular(10)),
color: Colors.blue
),
),
),
Expanded(
child: Container(
decoration: const BoxDecoration(
borderRadius: BorderRadius.only(bottomLeft: Radius.circular(10),bottomRight: Radius.circular(10)),
color: Colors.red
),
),
)
],
),
),
Positioned.fill(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Padding(
padding: EdgeInsets.only(left: 20),
child: CircleAvatar(
radius: 40,
backgroundColor: Colors.grey,
),
),
],
),
)
],
)
),
);
}
我对 flutter 还很陌生,我正在尝试制作一张包含两个部分的卡片,每个部分占 space 的一半。然后我想要一个位于卡片中心顶部的头像圆圈图像小部件,如图所示。
目前代码如下所示(包括两部分):
@override
Widget build(BuildContext context) {
// it enable scrolling on small device
return Center(
child: Card(
margin: const EdgeInsets.all(10.0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
color: cardColor,
child: Flex(
direction: Axis.vertical,
children: [
Expanded(
child: ClipRRect(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16)),
child: Container(
child: Image.asset("assets/images/card_background.jpg",
fit: BoxFit.fill),
)),
),
Expanded(
child: Column(
children: [
Container(
child: Text("Test"),
)
],
),
)
],
),
),
);
}
因此,我想知道如何才能让头像图像如图所示定位。或者如果我现在拥有的代码甚至有可能。在那种情况下,我想知道我应该使用哪些小部件来解决这个问题。
感谢您的帮助!
如果我没理解错的话,你想要一个 Card
的背景图片和一个位于顶部中央的 CircleAvatar
小部件。
您可以像这样使用 Stack
来做到这一点:
Card(
margin: const EdgeInsets.all(10),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
clipBehavior: Clip.antiAlias,
color: cardColor,
child: Stack(
children: [
Positioned.fill(
child: Image.asset(
'assets/images/card_background.jpg',
fit: BoxFit.fill,
),
),
const Positioned.fill(
child: Align(
alignment: Alignment.topCenter
child: CircleAvatar(
backgroundColor: Colors.orangeAccent,
),
),
)
],
)
),
你走在正确的轨道上,有一个Column
(或Flex
)和2个Expanded
来平分它。您只需要另一个 Stack
小部件来覆盖顶部的圆圈。您可以用 Align
小部件包裹圆圈并将其设置为对齐 center-left.
代码看起来像这样:
Stack
Column
- Expanded
- Expanded
Align
- Circle
没有什么是一个简单的 Stack 小部件无法解决的。
@override
Widget build(BuildContext context) {
// it enable scrolling on small device
return Center(
child: Card(
margin: const EdgeInsets.all(10.0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
color: Colors.blue,
child: Stack(
children: [
Flex(
direction: Axis.vertical,
children: [
Expanded(
child: ClipRRect(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16)),
child: Container(
color: Colors.red,
)),
),
Expanded(
child: Column(
children: [
Container(
child: Text("Test"),
)
],
),
)
],
),
// align a circle center and left, with a left margin
Align(
alignment: Alignment.centerLeft,
child: Container(
margin: const EdgeInsets.only(left: 20),
child: ClipOval(
child: Container(
width: 80,
height: 80,
color: Colors.black
)
)
)
)
]
),
),
);
}
您可以使用 Stack
小部件将小部件放置在其他小部件之上。
试试这个代码
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Stack(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
Expanded(
child: Container(
decoration: const BoxDecoration(
borderRadius: BorderRadius.only(topLeft: Radius.circular(10),topRight: Radius.circular(10)),
color: Colors.blue
),
),
),
Expanded(
child: Container(
decoration: const BoxDecoration(
borderRadius: BorderRadius.only(bottomLeft: Radius.circular(10),bottomRight: Radius.circular(10)),
color: Colors.red
),
),
)
],
),
),
Positioned.fill(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Padding(
padding: EdgeInsets.only(left: 20),
child: CircleAvatar(
radius: 40,
backgroundColor: Colors.grey,
),
),
],
),
)
],
)
),
);
}