How to set minWidth Container in Expand - flutter

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)),
),
],
);
}
}

Related

How to add backgroud like this in flutter

I want to add background that has circle like picture below:
And in my Figma, has asset like this:
And my code is like this:
Widget buildArea(int index) => Card(
color: ColorName.brandSecondaryBlue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
),
child: Container(
padding: const EdgeInsets.only(top: 20, bottom: 20),
child: buildAreaItem(),
),
);
Anyone else who know how to add it?
May not be a clean way but try Using a Stack widget and use Positioned widget inside.
Here's a sample for what you are trying to achieve.
Scaffold(
body: Center(
child: Stack(
children: [
Container(
width: 300,
height: 150,
decoration: BoxDecoration(
color: Colors.indigo,
borderRadius: BorderRadius.circular(20)
),
),
Positioned(
left: -50,
top: -35,
child: Stack(
alignment: AlignmentDirectional.center,
children:
[
Container(
width: 150,
height: 150,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(100)
),),
Container(
width: 100,
height: 100,
decoration: BoxDecoration(
color: Colors.indigo,
borderRadius: BorderRadius.circular(100)
),),
]
))
],
),
)
)
Try This Code:
import 'package:flutter/material.dart';
import 'package:flutter/gestures.dart';
import 'dart:ui';
import 'package:google_fonts/google_fonts.dart';
import 'package:myapp/utils.dart';
class circlescreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
double baseWidth = 428;
double fem = MediaQuery.of(context).size.width / baseWidth;
double ffem = fem * 0.97;
return Container(
width: double.infinity,
child: Container(
// iphone13promax1auq (1:2)
width: double.infinity,
decoration: BoxDecoration (
color: Color(0xff3241a0),
borderRadius: BorderRadius.circular(20*fem),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Container(
// ellipse1hmV (1:4)
margin: EdgeInsets.fromLTRB(0*fem, 0*fem, 237*fem, 272*fem),
width: 318*fem,
height: 318*fem,
decoration: BoxDecoration (
borderRadius: BorderRadius.circular(159*fem),
border: Border.all(color: Color(0xff3c4baf)),
),
),
Container(
// ellipse3jCP (1:6)
margin: EdgeInsets.fromLTRB(0*fem, 0*fem, 0*fem, 113*fem),
width: 198*fem,
height: 198*fem,
decoration: BoxDecoration (
borderRadius: BorderRadius.circular(99*fem),
border: Border.all(color: Color(0xff3c4baf)),
),
),
Container(
// ellipse2oi3 (1:5)
margin: EdgeInsets.fromLTRB(0*fem, 0*fem, 205*fem, 0*fem),
width: 318*fem,
height: 318*fem,
decoration: BoxDecoration (
borderRadius: BorderRadius.circular(159*fem),
border: Border.all(color: Color(0xff3c4baf)),
),
),
],
),
),
);
}
}
export your figma component with the just the background( purple with circles).
Then add that in assets and use it in the child of Card. So your widget tree would be :
Card
=>
Container( //with background decoration as image and necessary padding if any
)
=>
buildAreaItem()
You can also crop the image to get just the top corner ring or play with the fit property in DecorationImage widget.

Flutter half circle with multiple fill colors

I would like to create this in Flutter:
I know you can create a half circle like this.
But how I can get these multiple fill colors?
I know there is way to get this done with LinearGradient. (something like this)
But this might work, but I need to each color-section as a separated part/widget because I want to animate them in the next step.
How could I get this done?
You can do this using Custom Painter but then I understand it would be challenging to animate each color bar. I have been able to create something like you need
I used the ClipRRect widget to cut out the bottomLeft and bottomRight portions of a square -> SemiCircle.
Each Color bar is a Container and since you would like to animate each bar you can easily replace the Container with an AnimatedContainer and proceed from there. You might also need to make the widget stateful for animations.
class MyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
// Assuming constraints here.
// Play with width and height values
const double widgetWidth = 100;
const double widgetHeight = 60;
// To get a semicircle
const double bottomRadius = widgetWidth / 2;
//Since we have 5 colors . Each color bars height is 60/5 = 12
const double colorBarHeight = widgetHeight / 5;
return ClipRRect(
borderRadius: const BorderRadius.only(
bottomLeft: Radius.circular(bottomRadius),
bottomRight: Radius.circular(bottomRadius)),
child: SizedBox(
width: widgetWidth,
height: widgetHeight,
child: Column(
children: [
Container(
width: widgetWidth,height: colorBarHeight,color: Colors.green),
Container(
width: widgetWidth,height: colorBarHeight,color: Colors.orange),
Container(
width: widgetWidth,height: colorBarHeight,color: Colors.yellow),
Container(
width: widgetWidth, height: colorBarHeight, color: Colors.red),
Container(
width: widgetWidth, height: colorBarHeight, color: Colors.blue),
])));
}
}
Please try this below code:
class SemiCircle extends StatelessWidget {
const SemiCircle({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Center(
child: ClipRRect(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(300),
bottomRight: Radius.circular(300),
),
child: Container(
alignment: Alignment.center,
height: 100,
width: 200,
child: Column(
children: [
Container(
height: 10,
color: Colors.red,
),
Container(
height: 10,
color: Colors.yellow,
),
Container(
height: 10,
color: Colors.green,
),
Container(
height: 10,
color: Colors.red,
),
Container(
height: 10,
color: Colors.yellow,
),
Container(
height: 10,
color: Colors.green,
),
Container(
height: 10,
color: Colors.red,
),
Container(
height: 10,
color: Colors.yellow,
),
Container(
height: 10,
color: Colors.green,
),
Container(
height: 10,
color: Colors.red,
),
],
),
),
),
),
],
),
);
}
}
You will get an output like below:

Designing a Flutter button with image and text

If I just throw together an image and some text in a rounded-corner rectangle, the user will not know that they can "click here". But I don't have to bake my own solution. InkWell covers this scenario, complete with a nice shadow.
I am positioning
a custom clickable icon using the
InkWell
class, itself requiring to be inside an
Ink
instance.
import 'package:flutter/material.dart';
const boat_url = ('https://upload.wikimedia.org/wikipedia/commons/thumb/0/05/'
'Segelboot_Bodensee_Mainau_%28Foto_Hilarmont%29.JPG/'
'182px-Segelboot_Bodensee_Mainau_%28Foto_Hilarmont%29.JPG');
void main() {
runApp(MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Image',
home: Scaffold(
backgroundColor: Colors.grey,
body: MyImage(),
)));
}
class MyImage extends StatelessWidget {
MyImage({Key key,});
#override
Widget build(BuildContext context) {
Size sz = MediaQuery.of(context).size * 0.4;
double border = 4;
return Stack(children: [
Positioned(
top: 100,
left: 100,
width: sz.width,
height: sz.height,
child: Material(
child: Ink(
decoration: BoxDecoration(
boxShadow: <BoxShadow>[
new BoxShadow(
color: Colors.red,
blurRadius: 10.0,
offset: new Offset(30.0, 20.0),
),
],
border: Border.all(
color: Colors.blue,
width: border,
),
borderRadius: BorderRadius.circular(40),
),
child: InkWell(
onTap: (){/*..*/},
child: Column(
children: [
Container(
height: 4 * (sz.height - 2 * border) / 5,
alignment: Alignment.center,
child: Image.network(boat_url),
),
Container(
height: (sz.height - 2 * border) / 5,
child: FittedBox(
clipBehavior: Clip.antiAlias,
alignment: Alignment.centerLeft,
fit: BoxFit.fitHeight,
child: Text('A long descriptive sentence')),
)
],
)),
),
)),
]);
}
}
1- I'm not actually using Colors.white, and the Scaffold itself has
backgroundColor: Colors.grey. Where is the white background coming from?
2- When we talk of a "shadow", I'm expecting the shadow to be behind
the ink/inkwell object. Why does the shadow appear in front?
Related: 1
That white color is from the Material widget, to remove that you can use type param.
Material(
type: MaterialType.transparency,
child: Container(),
);
Here is code to achieve the custom button
Video link
Scaffold(
backgroundColor: Colors.blueGrey,
body: SafeArea(
child: Container(
decoration: BoxDecoration(
color: Colors.green.shade200,
border: Border.all(color: Colors.green),
borderRadius: BorderRadius.circular(5),
boxShadow: [
BoxShadow(
blurRadius: 5,
spreadRadius: 2,
color: Colors.black26,
)
]),
margin: const EdgeInsets.all(20),
child: Material(
type: MaterialType.transparency,
child: InkWell(
onTap: () {},
splashColor: Colors.black26,
child: IntrinsicHeight(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(mainAxisSize: MainAxisSize.min, children: [
Image.asset(
'assets/images/marked_tyre_base.png',
fit: BoxFit.cover,
width: 80,
height: 80,
),
const SizedBox(
height: 10,
),
Text(
'Tyre 1',
style: TextStyle(color: Colors.white),
)
]),
),
),
),
),
),
),
);
Screenshot:
Create a class, ImageTextButton:
class ImageTextButton extends StatelessWidget {
final VoidCallback onPressed;
final ImageProvider image;
final double imageHeight;
final double radius;
final Widget text;
ImageTextButton({
#required this.onPressed,
#required this.image,
this.imageHeight = 200,
this.radius = 28,
#required this.text,
});
#override
Widget build(BuildContext context) {
return Card(
elevation: 8,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(radius)),
clipBehavior: Clip.hardEdge,
child: InkWell(
onTap: onPressed,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Ink.image(
image: image,
height: imageHeight,
fit: BoxFit.cover,
),
SizedBox(height: 6),
text,
SizedBox(height: 6),
],
),
),
);
}
}
Usage:
ImageTextButton(
onPressed: () {},
image: AssetImage('chocolate_image'),
text: Text('Chocolate'),
)

Flutter multiple items in Row with Expanded/Flexible

I want to have more(in this example 4) items in Row. I tried use Expanded or Flexible or mainAxisAlignment: MainAxisAlignment.spaceEvenly to fill up all width of screen. But I want to heve items lets say specific width and height 50 pixels, and GestureDetector which is around item to be 1/4 of screen(4 items = full width). So everywhere I tap in the row something will be selected. My problem is that every my solution deforms items(circles) or circle must be very huge to width = height to not be deformed.
I also tried wrapping whole _ratingEmoji in Expanded and giving ratingItem.ratingIndicator constraints to max width but with same result.
Row of items:
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
for (var ratingItem in editGroceryRatingProvider.foodRatings)
_ratingEmoji(editGroceryRatingProvider, ratingItem, context),
],
),
Item:
Widget _ratingEmoji(EditGroceryRatingProvider editGroceryRatingProvider,
SelectedFoodRating ratingItem, BuildContext context) {
return GestureDetector(
child: ratingItem.selected
? Container(
width: MediaQuery.of(context).size.width / 8,
height: MediaQuery.of(context).size.width / 8,
padding: const EdgeInsets.all(2.0),
decoration: BoxDecoration(
border: Border.all(
color: Color(0xFF312ADB),
width: 3.0,
),
borderRadius: BorderRadius.circular(32.0)),
child: Center(
child: ratingItem.ratingIndicator,
),
)
: ratingItem.ratingIndicator,
onTap: () => editGroceryRatingProvider.updateSelectedRating(ratingItem),
);
}
RatingIndicator which is "circle" item to be on the screen:
Container(
decoration: BoxDecoration(
border: Border.all(
color: color,
width: 1.5,
),
borderRadius: BorderRadius.circular(64.0),
),
child: Container(
decoration: BoxDecoration(
border: Border.all(
color: Colors.white,
width: 3.0,
),
borderRadius: BorderRadius.circular(64.0),
),
child: ClipOval(
child: Container(
width: width ?? MediaQuery.of(context).size.width / 7,
height: height ?? MediaQuery.of(context).size.width / 7,
color: color,
),
),
),
);
Thanks a lot.
Update:
Items should stay as they are on screenshot, but "whole" row should be clickable(means even if you click between 2 items, one closer to click should be selected)
Check, please solution.
The whole area is clickable. You just need to add your item instead of mine.
#override
Widget build(BuildContext context) {
final colors = [Colors.red, Colors.blue, Colors.brown, Colors.cyan];
return Scaffold(
body: Container(
alignment: Alignment.center,
color: const Color(0xffFAFAFA),
child: Row(
children: List.generate(
colors.length,
(index) => Expanded(
child: GestureDetector(
onTap: () => print('Tapped:$index'),
child: Container(
height: 50,
color: Colors.transparent,
child: Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: colors[index],
),
),
)),
)),
),
),
);

How to make this screen responsive in Flutter?

I'm kinda confused with how responsive layouts are made with flutter can you guys point me to the right direction or where in my codes will be wrapped in Expanded widget?
I tried wrapping the containers with Extended but It keeps showing an error and I'm getting confused now. I'm still a beginner, to be honest. Thank you very much!
Also, when I searched I found out that I should avoid using hardcoded sizes most of the time. So I want to learn when to apply Extended widget in order to make my screen responsive.
my code is below:
import 'package:flutter/material.dart';
class RegisterPage extends StatefulWidget {
RegisterPage({Key key}) : super(key: key);
#override
_RegisterPageState createState() => _RegisterPageState();
}
class _RegisterPageState extends State<RegisterPage> {
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
backgroundColor: Color(0xff0D192A),
body: Container(
child: ListView(
children: <Widget>[
Column(
children: <Widget>[
Padding(
padding: EdgeInsets.all(10.0),
child: Container(
height: 200,
width: 200,
child: Image(
image: AssetImage("assets/images/vlogo.png"),
),
),
),
Padding(
padding: EdgeInsets.all(40.0),
child: Center(
child: Text("Register an Account",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 20)),
)),
Padding(
padding: EdgeInsets.fromLTRB(20, 0, 0, 0),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Text("Email Address",
style: TextStyle(
fontSize: 10.0, color: Colors.grey[400])),
],
),
],
),
),
SizedBox(height:10.0),
Container(
margin: EdgeInsets.fromLTRB(20, 0, 20, 0),
padding: EdgeInsets.all(5.0),
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(10),
),
child: Center(
child: Padding(
padding: EdgeInsets.fromLTRB(20, 0, 0, 0),
child: TextField(
decoration: InputDecoration(
border: InputBorder.none,
hintText: "Enter your email address",
hintStyle: TextStyle(color: Colors.grey[400]),
),
),
),
)
),
SizedBox(height:20.0),
Padding(
padding: EdgeInsets.fromLTRB(20, 0, 0, 0),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Text("Choose Password",
style: TextStyle(
fontSize: 10.0, color: Colors.grey[400])),
],
),
],
),
),
SizedBox(height:10.0),
Container(
margin: EdgeInsets.fromLTRB(20, 0, 20, 0),
padding: EdgeInsets.all(5.0),
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(10),
),
child: Center(
child: Padding(
padding: EdgeInsets.fromLTRB(20, 0, 0, 0),
child: TextField(
decoration: InputDecoration(
border: InputBorder.none,
hintText: "Enter your email address",
hintStyle: TextStyle(color: Colors.grey[400]),
),
),
),
)
),
SizedBox(height: 50),
Padding(
padding: EdgeInsets.fromLTRB(20, 0, 20, 0),
child: InkWell(
onTap: () {
setState(() {
});
},
child: Container(
height: 50,
decoration: BoxDecoration(
color: Color.fromRGBO(211, 184, 117, 100)
),
child: Center(
child: Text("Login", style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 20),
),
),
),
),
),
],
),
],
),
),
),
);
}
}
Explore this plugin: This is one of the most effective plugins I have ever used for making responsive design.
https://pub.dev/packages/responsive_screen
Or
Use MediQuery() for getting the screen height and width i.e:-
Example:
#override
Widget build(BuildContext context) {
dynamic screenHeight = MediaQuery.of(context).size.height;
dynamic screenwidth = MediaQuery.of(context).size.width;
//use screenHeight and screenWidth variable for defining the height and
//width of the Widgets.
return Container(
height:screenHeight * .2, //It will take the 20% height of the screen
width: screenwidth * .5, //It will take the 50% width of the screen
//height: screenHeight, //It will take 100% height
child: Image(
image: AssetImage("assets/images/vlogo.png"),
);
}
You can make each screen responsive in flutter by just using MediaQuery or LayoutBuilder Concepts.
For your application, replace all your custom sizes like
width : MediaQuery.of(context).size.width * 0.1
height : MediaQuery.of(context).size.height * 0.3
MediaQuery gives you the sizes and orientation of the screen.
Even your padding, margin and other dimensions also should be calculated using MediaQuery to make it responsive.
Here, MediaQuery.of(context).size.width will give you the width of the current device screen and MediaQuery.of(context).size.height will give you the height of the current device screen.
Also, you can use LayoutBuilder Widget like,
LayoutBuilder(
builder: (context, constraints) {
if(constraints.maxWidth > 500) {
getLandscapeLayout();
} else {
getPortraitLayout();
}
},
)
LayoutBuilder is a widget which provides the dimensions of its parent so we can know how much space we have for the widget and can build it our child accordingly.
So these are two most powerful concepts are available in flutter to make your apps fully responsive.