I'm fairly new to flutter and I'm trying to have a card that has two sections each taking half of the space. And then I want an avatar circle image widget that lies on top in the centre of the card as illustrated in the image.
For now the code looks like this (includes the two sections):
@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"),
)
],
),
)
],
),
),
);
}
I am therefore wondering how I can get the avatar image positioned as illustrated in the image. Or if it is even possible with the code I have until now. In that case, I'm wondering which widgets I should use to solve this.
Thanks for any help!
CodePudding user response:
If I understand you correctly, you want a Card
with a background image and a CircleAvatar
widget in the top center.
You do this by using Stack
like so:
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,
),
),
)
],
)
),
CodePudding user response:
You are on the right track, having a Column
(or Flex
) and 2 Expanded
to equally divide it. You just need another Stack
widget to overlay the circle on top. You can wrap the circle with an Align
widget and set it to align center-left.
The code would look something like:
Stack
Column
- Expanded
- Expanded
Align
- Circle
CodePudding user response:
Nothing that a simple Stack widget can't solve.
@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
)
)
)
)
]
),
),
);
}
CodePudding user response:
You can use Stack
widget to place widgets on top of other widgets.
Try this code
@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,
),
),
],
),
)
],
)
),
);
}