How to display cards on a board (for a card game)? - flutter

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

Related

is there a way to implement a target line in a horizontal bar chart in flutter?

I want to do like this chart
enter image description here
I have searched in different packages trying to find a bar chart with properties that support this but I didn't find yet.
Try to play with Stack widget
class BCw extends StatefulWidget {
const BCw({super.key});
#override
State<BCw> createState() => _BCwState();
}
class _BCwState extends State<BCw> {
double value = .3;
#override
Widget build(BuildContext context) {
return Scaffold(
body: LayoutBuilder(
builder: (p0, constraints) => Column(
children: [
Slider(
value: value,
onChanged: (v) {
setState(() {
value = v;
});
},
),
SizedBox(
height: 64,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: Stack(
children: [
Positioned(
top: 8,
bottom: 8,
left: 0,
right: constraints.maxWidth / 2,
child: Container(
height: 40,
color: Colors.green,
),
),
Positioned(
top: 0,
bottom: 0,
left: constraints.maxWidth * value,
child: VerticalDivider(
color: Colors.grey,
thickness: 5,
),
)
],
),
),
Text("${value.toStringAsFixed(2)}"),
],
),
),
],
),
),
);
}
}

How to break a Text (placed in a Stack widget) into multiple lines in Flutter?

I want to implement the following design in Flutter, specifically the rounded rectangle with the Text placed on it.
I have used the Stack widget to position the Text at the bottom left of the Container, but the problem is that the Text goes in one line beyond the Stack boundary, instead of breaking into the second line. For simplicity sake, I have written a simpler code as following:
#override
Widget build(BuildContext context) {
return Center(
child: Stack(
children: [
Container(
width: 150,
height: 150,
color: Colors.teal.shade300,
),
const Positioned(
left: 16,
bottom: 16,
child: Text(
"A very looooooooooooooooong teeeeeeeext",
maxLines: 2,
softWrap: true,
),
),
],
),
);
}
And the result is:
So how can I break the Text into the second line (not by using \n character), in this scenario. Or, if there is another solution other than using Stack, please tell me. Thanks.
You can use align inside the container instead of using stack
#override
Widget build(BuildContext context) {
return Center(
child: Container(
width: 150,
height: 150,
color: Colors.teal.shade300,
child: const Align(
alignment: Alignment.bottomLeft,
child: Text(
"A very looooooooooooooooong teeeeeeeext",
maxLines: 2,
softWrap: true,
),
),
),
);
}
You can use GridView to implement the following design. Like this:
GridView(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 16.0,
crossAxisSpacing: 16.0,
),
children: [
Container(
width: 150,
height: 150,
color: Colors.teal.shade300,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('title1'),
Text('21222222222222222222222222222')
],
),
),
Container(
width: 150,
height: 150,
color: Colors.teal.shade300,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('title1'),
Text('21222222222222222222222222222')
],
),
),
Container(
width: 150,
height: 150,
color: Colors.teal.shade300,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('title1'),
Text('21222222222222222222222222222')
],
),
),
Container(
width: 150,
height: 150,
color: Colors.teal.shade300,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('title1'),
Text('21222222222222222222222222222')
],
),
),
],
)
Or you can use GridView.builder.
Use Expanded Widget
#override
Widget build(BuildContext context) {
return Center(
child: Stack(
children: [
Container(
width: 150,
height: 150,
color: Colors.teal.shade300,
),
const Positioned(
left: 16,
bottom: 16,
child: Expanded(
Text(
"A very looooooooooooooooong teeeeeeeext",
maxLines: 2,
softWrapenter code here: true,
),
),
),
],
),
);
}
Use layout like this for multiple line text on stack.
Stack(
children: [
CustomPaintCurves(),
Positioned(
top: 0.0,
left: 0.0,
right: 0.0,
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Image.asset(
AppAssets.icon_button_background,
gaplessPlayback: true,
fit: BoxFit.cover,
height: 80,
width: 80),
),
const Padding(
padding: EdgeInsets.all(8.0),
child: Text(
StringManager.appName,
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold,
),
),
),
const Padding(
padding: EdgeInsets.all(8.0),
child: Text(StringManager.aboutUsDescription),
),
],
),
),
],
),
A sample code snippet
Stack(
children: [
//! other children in this stack
Positioned(
left: 20, //! giving it random position
bottom: 20,
width: MediaQuery.of(context).size.width * 0.80, //! so that the `Text` widget knows where it overflows
child: const Text(
"Some Very Long Text Here .......", //! the long text you want to clip
overflow: TextOverflow.ellipsis, //! type of overflow
softWrap: false,
maxLines: 3, //! max lines before clipping the text
),
),
],
);
Explanation:
Gave random positions to the text widget (bottom left) of its container. Also gave width to the 'Positioned' widget so that the 'Text' widget knows where the text actually overflows and where it needs to apply the overflow properties.
I used 'TextOverflow.ellipsis' so that the overflowed text would go into the next line, but I specified how many lines of text I want to see (i.e. 'maxLines: 3') before the rest of the text is replaced with '...'.
this problem occur because inside stack you not applied any width of Text widget (child widget), so it will not take any width,
so in your case wrap your text widget into SizeBox and applied width , it will work.
watch full code
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
final String title;
const MyHomePage({
Key? key,
required this.title,
}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Stack(
children: [
Container(
width: 150,
height: 150,
color: Colors.teal.shade300,
),
const Positioned(
left: 16,
bottom: 16,
child: SizedBox(
width: 150,
child: Text(
"A very looooooooooooooooong teeeeeeeext",
maxLines: 2,
softWrap: true,
),
),
),
],
),
),
);
}
}
see the result

Make Listeview work nested inside of column inside of a container in flutter

I am trying and make a Listeview work, which is nested inside of column that is nested inside of a container in flutter. The container is supposed to be a dialog. I think the problem is that the container has no defined hight (it is supposed to adapt to the screen size). With the current code I get a bottom overflow. Maybe because of the padding of the container?
I tried differen variants with expanded, flexible and singlechildscrollview but I can't make it work. The standard tip, wrap the ListView with Expanded seems not to work.
Thanks for your help!
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Dialog',
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
title: const Text('Welcome to Flutter'),
),
body: Center(
child: Column(
children: [
MaCard(mitarbeiterName: "Name"),
CustomDialogBoxRow(
title: "Sturmtruppler",
descriptions: "wird noch weichen",
text: "text")
],
),
),
),
);
}
}
class Constants {
Constants._();
static const double padding = 20;
static const double avatarRadius = 100;
static const double buttonHight = 100;
}
class CustomDialogBoxRow extends StatefulWidget {
final String title, descriptions, text;
const CustomDialogBoxRow({
Key? key,
required this.title,
required this.descriptions,
required this.text,
}) : super(key: key);
#override
_CustomDialogBoxRowState createState() => _CustomDialogBoxRowState();
}
class _CustomDialogBoxRowState extends State<CustomDialogBoxRow> {
#override
Widget build(BuildContext context) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(Constants.padding),
),
elevation: 0,
backgroundColor: Colors.transparent,
child: contentBox(context),
);
}
contentBox(context) {
return Stack(
children: <Widget>[
Container(
constraints: const BoxConstraints(minWidth: 400, maxWidth: 800),
padding: const EdgeInsets.only(
left: Constants.padding,
right: Constants.padding,
bottom: Constants.padding),
margin: const EdgeInsets.only(top: Constants.avatarRadius),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Colors.white,
borderRadius: BorderRadius.circular(Constants.padding),
boxShadow: [
const BoxShadow(
color: const Color.fromARGB(255, 79, 73, 73),
offset: const Offset(0, 5),
blurRadius: 5),
]),
child: Column(
children: [
SizedBox(
height: Constants.avatarRadius,
child: Row(
children: [
const SizedBox(
child: const Placeholder(),
),
const Expanded(
child: Placeholder(),
),
],
),
),
SingleChildScrollView(
child: Column(
children: [
SizedBox(
height: 50,
child: Text("bla"),
),
SizedBox(
height: 50,
child: Text("bla"),
),
SizedBox(
height: 50,
child: Text("bla"),
),
SizedBox(
height: 50,
child: Text("bla"),
)
],
),
)
],
),
),
Positioned(
left: Constants.padding,
right: Constants.padding,
child: Stack(
children: [
Container(
child: Align(
alignment: Alignment.topLeft,
child: Container(
width: Constants.avatarRadius * 2,
height: Constants.avatarRadius * 2,
child: const CircleAvatar(
radius: Constants.avatarRadius * 2,
backgroundImage: AssetImage('assets/images/SBE.jpg'),
),
),
),
),
],
),
),
],
);
}
}
class MaCard extends StatefulWidget {
MaCard({
Key? key,
required this.mitarbeiterName,
}) : super(key: key);
final String mitarbeiterName;
#override
State<MaCard> createState() => _MaCardState();
}
class _MaCardState extends State<MaCard> {
#override
Widget build(BuildContext context) {
return Card(
child: InkWell(
onTap: () {
print("card taped");
/*showDialog(context: context, builder: (BuildContext context) {
return
})*/
showDialog(
context: context,
builder: (BuildContext context) {
return CustomDialogBoxRow(
title: "Stormtrouper",
descriptions: "Jojo, this is card",
text: "Roger Roger",
);
});
},
child: SizedBox(
height: Constants.buttonHight,
width: 300,
child: Center(child: Text(widget.mitarbeiterName)),
),
));
}
}
Here is picture of what it should look like. My wonderful handdrawing is supposed to be the scrollable content.
Goal
It would be better using LayoutBuilder to get parent constraints and size the inner elements. Also You need to wrap with Expaned to get available spaces for infinite size widget.
I will highly recommend to check this video from Flutter.
Changes are made
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Dialog',
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
title: const Text('Welcome to Flutter'),
),
body: Center(
child: Column(
children: [
MaCard(mitarbeiterName: "Name"),
Expanded( //here
child: CustomDialogBoxRow(
title: "Sturmtruppler",
descriptions: "wird noch weichen",
text: "text"),
)
],
),
),
),
);
}
}
And on contentBox
contentBox(context) {
return LayoutBuilder(builder: (context, constraints) {
print(constraints);
return SizedBox(
width: constraints.maxWidth,
height: constraints.maxHeight,
child: Stack(
children: <Widget>[
Container(
constraints: const BoxConstraints(minWidth: 400, maxWidth: 800),
padding: const EdgeInsets.only(
left: Constants.padding,
right: Constants.padding,
bottom: Constants.padding),
margin: const EdgeInsets.only(top: Constants.avatarRadius),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Colors.white,
borderRadius: BorderRadius.circular(Constants.padding),
boxShadow: const [
BoxShadow(
color: Color.fromARGB(255, 79, 73, 73),
offset: Offset(0, 5),
blurRadius: 5),
]),
child: Column(
children: [
SizedBox(
height: Constants.avatarRadius,
child: Row(
children: [
const Expanded(
child: const Placeholder(),
),
const Expanded(
child: Placeholder(),
),
],
),
),
Expanded(
// or sizedBOx ( constraints.maxHeight- Constants.avatarRadius,)
child: SingleChildScrollView(
child: Column(
children: [
SizedBox(
height: 450,
child: Text("bla"),
),
SizedBox(
height: 50,
child: Text("bla"),
),
SizedBox(
height: 50,
child: Text("bla"),
),
SizedBox(
height: 50,
child: Text("bla"),
)
],
),
),
)
],
),
),
// Positioned(
// left: Constants.padding,
// right: Constants.padding,
// child: Stack(
// children: [
// Container(
// child: Align(
// alignment: Alignment.topLeft,
// child: Container(
// width: Constants.avatarRadius * 2,
// height: Constants.avatarRadius * 2,
// child: const CircleAvatar(
// radius: Constants.avatarRadius * 2,
// backgroundImage: AssetImage('assets/images/SBE.jpg'),
// ),
// ),
// ),
// ),
// ],
// ),
// ),
//
],
),
);
});
}

Flutter set widget position exactly center of the screen

I want to put a container widget in the middle of the device screen. However, since I used the SizedBox() and SvgPicture.asset() widgets before that, the container does not come right in the middle of the device. How can I do this?
This is my code:
class CenterWidget extends StatefulWidget {
const CenterWidget({Key? key}) : super(key: key);
#override
_CenterWidgetState createState() => _CenterWidgetState();
}
class _CenterWidgetState extends State<CenterWidget> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 30),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
const SizedBox(height: 56),
SvgPicture.asset(ImageConstants.instance.logoSvg,
width: (MediaQuery.of(context).size.width - 60) / 2),
Expanded(
child: Center(
child: Container(
color: Colors.red,
width: 100,
height: 100,
),
),
),
],
),
),
),
);
}
}
Use a top center aligned stack, and put the widget you want to be centered within a Positioned.fill widget. You can put the spacer and logo in their own column to keep them arranged vertically:
class _CenterWidgetState extends State<CenterWidget> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 30),
child: Stack(
alignment: Alignment.topCenter,
children: [
Column(
children: [
const SizedBox(height: 56),
SvgPicture.asset(ImageConstants.instance.logoSvg,
width: (MediaQuery.of(context).size.width - 60) / 2),
],
),
Positioned.fill(
child: Center(
child: Container(
color: Colors.red,
width: 100,
height: 100,
),
),
),
],
),
),
),
);
}
}

is there a way to embed a SingleChildScrollView (Vertical) within another SingleChildScrollView(Horizontal) in Flutter

In my app there is a SingleChildScrollView(with scrollable direction as Horizontal) which has a N number of containers.
Is there a way to embed a the SingleChildScrollView(with scrollable direction as Horizontal) into a SingleChildScrollView (with scrollable direction as Vertical) in Flutter.
for example:
class HomeBody extends StatelessWidget {
#override
Widget build(BuildContext context) {
return SafeArea(
child: Padding(
padding: sidePadding,
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
HomeAppbar(),
addVerticalSpace(15),
Text(
'Welcome, Jack',
style: themeData.textTheme.headline1,
),
addVerticalSpace(15),
SearchField(
width: mediasize.width - 2 * screenHorizontalPadding,
height: mediasize.height,
),
addVerticalSpace(25),
//I want to add a SingleChildScrollView (Vertical Direction) from this point to
TitleMoreBar(barTitle: 'Trending'),
addVerticalSpace(15),
//the FullProductCardHorizontalList() has a SingleChildScrollView(Horizontal direction)
FullProductCardHorizontalList(),
addVerticalSpace(25),
TitleMoreBar(barTitle: 'Popular Brands'),
addVerticalSpace(25),
//the BrandCardList() has a SingleChildScrollView(Horizontal direction)
BrandCardList(),
// this where the SingleChildScrollView (Vertical) should end
],
),
),
),
);
}
Yes, you can do this like:
import 'package:flutter/material.dart';
class ScrollTraining extends StatefulWidget {
#override
_ScrollingTraining createState() => _ScrollingTraining();
}
class _ScrollingTraining extends State<ScrollTraining> {
double mWidth;
#override
Widget build(BuildContext context) {
mWidth = MediaQuery.of(context).size.width;
return Scaffold(
appBar: AppBar(),
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: mWidth,
height: 400,
color: Colors.indigo,
margin: EdgeInsets.symmetric(vertical: 8.0),
alignment: Alignment.center,
child: Text("Fixed Box"),
),
Container(
width: mWidth,
height: 200,
margin: EdgeInsets.symmetric(vertical: 8.0),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: getChildren(),
),
),
),
Container(
width: mWidth,
height: 400,
color: Colors.brown,
margin: EdgeInsets.symmetric(vertical: 8.0),
alignment: Alignment.center,
child: Text("Fixed Box"),
),
Container(
width: mWidth,
height: 200,
margin: EdgeInsets.symmetric(vertical: 8.0),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: getChildren(),
),
),
),
],
),
),
);
}
List<Widget> getChildren() {
List<Widget> output = List();
List<Color> colorList = [
Colors.redAccent,
Colors.deepOrange,
Colors.orangeAccent,
Colors.yellow,
Colors.lightGreenAccent,
Colors.green,
Colors.greenAccent,
Colors.blue,
Colors.purpleAccent,
Colors.pink,
];
for (int i = 0; i < 10; i++) {
output.add(Container(
width: 140,
height: 200,
color: colorList[i],
));
}
return output;
}
}
I hope it is useful for you.