I am trying to add a header card which will be displayed on the upper-left edge of a flutter card, so far I haven't been able to achieve that. This is an example of what I want
Being new to flutter, I didn't know there was a Stack widget. The solution is to stack two cards wrapped in Positioned widgets.
class SummaryCard extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Positioned(
left: 0,
top: 40,
height: 200,
width: 350,
child: Card(
color: Colors.blue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)
),
),
),
Positioned(
left: 20,
top: 0,
height: 100,
width: 100,
child: Card(
color: Colors.green,
elevation: 10.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)
),
),
),
],
);
}
}
You need to wrap header card with Align Widget.
Here is a full code:
class Cards extends StatefulWidget {
#override
_CardsState createState() => _CardsState();
}
class _CardsState extends State<Cards> {
#override
Widget build(BuildContext context) {
return Container(
height: 200,
width: 200,
child: Card(
elevation: 20,
child: Align(
alignment: Alignment.topLeft,
child: Container(
width:100,
height: 60,
child: Card(
elevation: 10,
child: Text("header"),
),
),
),
),
);
}
}
Containers are just for height and width control.
And here is a screenshot:
Related
I'm having issue while making the dashboard for my WebApp. I'm trying to make my webApp responsive. But not able to make it. Here is the image with the code for what I tried.
import 'package:flutter/material.dart';
class MyHomeScreen extends StatefulWidget {
const MyHomeScreen({super.key});
#override
State<MyHomeScreen> createState() => _MyHomeScreenState();
}
class _MyHomeScreenState extends State<MyHomeScreen> {
List<Widget> customWidgetList = [
Container(
height: 100,
width: 200,
color: Colors.grey.shade200,
),
Container(
height: 300,
width: 200,
color: Colors.grey.shade200,
),
Container(
height: 100,
width: 200,
color: Colors.grey.shade200,
),
Container(
height: 100,
width: 200,
color: Colors.grey.shade200,
),
Container(
height: 200,
width: 200,
color: Colors.grey.shade200,
),
Container(
height: 100,
width: 200,
color: Colors.grey.shade200,
),
];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Responsiveness')),
body: Wrap(
spacing: 2.0,
runSpacing: 2.0,
clipBehavior: Clip.antiAlias,
children: customWidgetList,
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: const Icon(Icons.add),
),
);
}
}
Result of above code :
Where as I want to fill all the empty spaces. Here is the image of what I want to do it.
Simple answer is to add direction: Axis.vertical to Wrap widget.
The correct answer is to create your own LayoutBuilder and calculate for each Container its correct position.
The easiest is to use https://pub.dev/packages/flutter_staggered_grid_view
I'm implementing a phone app for playing UNO using flutter (and dart), and I'm stuck with how I should display the cards on the board.
This is what I would like my code to look like
and this is what my code result looks like.
import 'package:flutter/material.dart';
import 'card.dart';
class Partida extends StatefulWidget {
const Partida({ Key? key }) : super(key: key);
#override
State<Partida> createState() => _PartidaState();
}
class _PartidaState extends State<Partida> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color.fromARGB(255, 19, 107, 22),
body: Center(
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
MyCard(),
MyCard(),
],
),
// MyCard(),
// Row(
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// // MyCard(),
// MyCard(),
// ]
// ),
],
),
),
),
);
}
}
Thanks in advance.
You can use the Stack() widget to achieve this. Start by giving clipBehaviour:Clip.none which will help overflow the cards when u stack multiple of them.
Then use the Positioned() widget to make them shift to left using property called left: 50 (or whatever your preferred number). This will shift the cards to left.
class MyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Stack(
clipBehavior: Clip.none,
alignment: AlignmentDirectional.bottomCenter,
children: const [
ColoredBox(
color: Colors.red,
child: SizedBox(
height: 100,
width: 80,
),
),
Positioned(
left: 50,
bottom: 0,
child: ColoredBox(
color: Colors.green,
child: SizedBox(
height: 100,
width: 80,
),
),
),
Positioned(
left: 100,
bottom: 0,
child: ColoredBox(
color: Colors.blue,
child: SizedBox(
height: 100,
width: 80,
),
),
),
Positioned(
left: 150,
bottom: 0,
child: ColoredBox(
color: Colors.yellow,
child: SizedBox(
height: 100,
width: 80,
),
),
),
],
);
}
}
Output
I using flutter to build the Web Application,
I have a response problem, I want my window to be as small as 600 dp, and when zoomed horizontally, the middle container will automatically scale, but the smallest is 200 dp.
I tried to write the code as follows, but it doesn't work as I expected. When I shrink to width less than 600, main container keeps automatically shrink and shrink to less than 200 db.
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: 200,
height: 600,
margin: EdgeInsets.only(right: 20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20)),
),
Expanded(
child: Container(
margin: EdgeInsets.symmetric(horizontal: 20),
constraints: BoxConstraints(minWidth: 300),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.8),
borderRadius: BorderRadius.circular(20)),
child: BlocBuilder<HomeBloc, HomeState>(
builder: (context, state) {
return state.widget;
}),
),
),
Container(
width: 200,
height: 600,
margin: EdgeInsets.only(right: 20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20)),
),
],
),
Have you tried using ConstrainedBox instead of regular Container?
It has properties minHeigth and minWidth / maxHeight and maxWidth.
I found that ConstrainedBox's minWidth is ignored in Row widget.
So I implemented center widget's dynamic width by using 'MediaQuery' like what you want.
But if you decrease width, the overflow issue is happened.
So I changed Row widget to ListView widget to fix overflow issue.
import 'package:flutter/material.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
double centerWidth = MediaQuery.of(context).size.width - 480;
return ListView(
scrollDirection: Axis.horizontal,
children: [
Container(
width: 200,
height: 600,
margin: EdgeInsets.only(left: 20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20)),
),
Container(
width: centerWidth < 300 ? 300 : centerWidth,
margin: EdgeInsets.symmetric(horizontal: 20),
constraints: BoxConstraints(minWidth: 150, ),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.8),
borderRadius: BorderRadius.circular(20),
),
child: Text(
'Hello, World!',
style: Theme.of(context).textTheme.headline4,
),
),
Container(
width: 200,
height: 600,
margin: EdgeInsets.only(right: 20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20)),
),
],
);
}
}
I'm working on a Flutter project and I am trying to use the OverflowBox widget.
I have a list of widgets in a Column, one of them, in the middle is supposed to overflow the others based on some events by the user.
Here is a simplified version of my code.
The red Container needs to display the green Container that overflows it at the top and the bottom.
But as you can see on the image, the green Container is only visible above the previous Container (the blue one) but not on the next one (the black Container). It looks like it is behind.
class MyScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
height: 100,
width: 100,
color: Colors.blue,
),
Container(
height: 100,
width: 100,
color: Colors.red,
child: Center(
child: OverflowBox(
maxHeight: 150,
child: Container(
color: Colors.green,
height: 150,
width: 50,
),
),
),
),
Container(
height: 100,
width: 100,
color: Colors.black,
)
],
);
}
}
How can I get my green Container to be above the black one too ?
EDIT: For functionality purposes, I need the green Container to be a child/be created by the red Container (and not by the list where I could use a Stack widget). I need the logic to be inside the red and green ones.
It still uses Stack, but Green Container is still part of Red Container.
And it might be difficult to calculate margin if Container has dynamic height.
class MyScreen extends StatelessWidget {
const MyScreen({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
Container(
height: 100,
width: 100,
color: Colors.blue,
),
Container(
margin: const EdgeInsets.only(top: 200),
height: 100,
width: 100,
color: Colors.black,
),
Container(
margin: const EdgeInsets.only(top: 100),
height: 100,
width: 100,
color: Colors.red,
child: Center(
child: OverflowBox(
maxHeight: 150,
child: Container(
height: 150,
width: 50,
color: Colors.green,
),
),
),
),
],
),
);
}
}
Use of overlay, maybe solve your problem.
OverlayState? overlayState = Overlay.of(context);
I tried your code snipped and failed to getting the design that you particularly wishing to achieve.
I have anther way to get such type of design. Which ia using Stacl() widget
Here is an complete example code snippet
import 'package:flutter/material.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyScreen(),
),
),
);
}
}
class MyScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Stack(
children: [
Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
height: MediaQuery.of(context).size.height/3,
width: MediaQuery.of(context).size.width,
color: Colors.blue,
),
Container(
height: MediaQuery.of(context).size.height/3,
width: MediaQuery.of(context).size.width,
color: Colors.red,
),
Container(
height: MediaQuery.of(context).size.height/3,
width: MediaQuery.of(context).size.width,
color: Colors.black,
)
],
),
Positioned(
// to set a specific position of your widget use Positioned inside a Stack() widget
/*
bottom: 50,
top: MediaQuery.of(context).size.height/3,
left: 100,
right: 100,
*/
child: OverflowBox(
child: Container(
color: Colors.green,
height: MediaQuery.of(context).size.height/2,
width: 100,
),
),
),
],
);
}
}
Output:
I am using a SingleChildScrollView with a Stack as its first element. The Stack contains two containers. The second one is positioned at bottom: 0.0 using a Positioned.
I highly simplified my view for this post to focus only on this issue. When I scroll slowly, you can see that the white container is "glitching" and you see a line that is the bottom of the first child of the stack.
Here is the view:
Not that's what happen when I scroll down, I have no clue why it's glitching like that:
View:
return Container(color: Colors.white, child: SingleChildScrollView(child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
HeaderComponent(),
Container(height: 600, width: MediaQuery.of(context).size.width)
]
)));
Header Component
class _HeaderComponentState extends State<HeaderComponent> {
#override
Widget build(BuildContext context) {
return Stack(
children: [
Container(height: 245.0, width: MediaQuery.of(context).size.width, color: Colors.red),
Positioned(bottom: 0.0, child: Container(height: 40.0, width:
MediaQuery.of(context).size.width, color: Colors.white)),
],
);
}
}
If that, just add bottom padding 0.2 at first child.
class HeaderComponent extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Stack(
children: [
Container(
height: 245.0,
padding: EdgeInsets.only(bottom: 0.2),
width: MediaQuery.of(context).size.width,
color: Colors.red),
Positioned(
bottom: 0.0,
child: Container(
height: 40.0,
width: MediaQuery.of(context).size.width,
color: Colors.white)),
],
);
}
}
I don't know root cause. But Positoned's 'bottom: 0.0' occurs upper container's background color a little during scrolling.
So when I set 'bottom: -0.2', this problem is not occured.
But it does not looks cool...
class HeaderComponent extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Stack(
children: [
Container(
height: 245.0,
width: MediaQuery.of(context).size.width,
color: Colors.red),
Positioned(
bottom: -0.2,
child: Container(
height: 40.0,
width: MediaQuery.of(context).size.width,
color: Colors.white)),
],
);
}
}
I suggest another solution like below.
class HeaderComponent extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
height: 245.0,
child: Column(
children: <Widget>[
Expanded(
child: Container(
width: MediaQuery.of(context).size.width, color: Colors.red),
),
Container(
height: 40.0,
width: MediaQuery.of(context).size.width,
color: Colors.white)
],
),
);
}
}