I am trying to implement this kind of UI. But i can't find a way to place image outside the container.(Check the image )
Hey you can use Stack widget to overlap from card, use Positioned to align your widget at particular position.
For - Eg.
Stack(
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 20),
child: Card(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: MediaQuery.of(context).size.width*0.6,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children:const [
Text("Title Text "),
Text("Body text"),
],
),
),
const Spacer(),
],
),
),
),
),
Positioned(
left: MediaQuery.of(context).size.width*0.65,
top: -10,
bottom: 15,
child: Image.asset("assets/sample.png", fit:BoxFit.fill,), // replace your image with Image.assets here
),
Positioned(
right: 20,
top: 0,
bottom: 0,
child: IconButton(onPressed: (){}, icon: const Icon(Icons.add_circle),),
),
],
)
For more details about Stack
Output will come like this -
You can use Stack widget first put Image widget inside it and then Container widget
import 'package:flutter/material.dart';
const 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) {
return Stack(
alignment : Alignment.center,
children :[
Image.network('https://image.shutterstock.com/image-vector/sample-stamp-rubber-style-red-260nw-1811246308.jpg'),
Container( child :const Text('test',style : TextStyle(color: Colors.black ,fontSize: 20.00))),
],
);
}
}
Related
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
I am getting an error with a single listing page or detailed page.
It shows the method [] was called on null.
But is as defined some itemData in main dart file it also showa same error. please help me to solve this error.
this is my DetailPage.dart file
import 'package:flutter/material.dart';
import 'package:uidesign/custom/BorderIcon.dart';
import 'package:uidesign/custom/OptionButton.dart';
import 'package:uidesign/utils/constants.dart';
import 'package:uidesign/utils/custom_functions.dart';
import 'package:uidesign/utils/widget_functions.dart';
class DetailPage extends StatelessWidget {
final dynamic itemData;
const DetailPage({super.key, #required this.itemData});
//DetailPage({Key? key,#required this.itemData}) : super(key: key);
#override
Widget build(BuildContext context){
final Size size = MediaQuery.of(context).size;
final ThemeData themeData = Theme.of(context);
final double padding = 25;
final sidePadding = EdgeInsets.symmetric(horizontal: padding);
return SafeArea(
child: Scaffold(
backgroundColor: COLOR_WHITE,
body: Container(
width: size.width,
height: size.height,
child: Stack(
children: [
SingleChildScrollView(
physics: BouncingScrollPhysics(),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Stack(
children: [
Image.asset(itemData["image"]),
Positioned(
width: size.width,
top: padding,
child: Padding(
padding: sidePadding,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
InkWell(
onTap: (){
Navigator.pop(context);
},
child: BorderIcon(
padding: new EdgeInsets.all(0.0),
height: 50,
width: 50,
child: Icon(
Icons.keyboard_backspace, color:COLOR_BLACK,
),
),
),
BorderIcon(
padding: new EdgeInsets.all(0.0),
width: 50,
height: 50,
child: Icon(Icons.favorite_border, color: COLOR_BLACK),
),
],
),
),
),
],
),
addVerticalSpace(padding),
Padding(
padding: sidePadding,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("${formatCurrency(itemData["amount"])}",style: themeData.textTheme.headline1,),
addVerticalSpace(5),
Text("\$${itemData["address"]}",style: themeData.textTheme.subtitle2,),
]
),
BorderIcon(
width: 0,
height: 0,
child: Text("20 Hours ago",style: themeData.textTheme.headline5,),padding: const EdgeInsets.symmetric(vertical: 15,horizontal: 15),
)
],
),
),
addVerticalSpace(padding),
Padding(
padding: sidePadding,
child: Text("House Information",style: themeData.textTheme.headline4,),
),
addVerticalSpace(padding),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
physics: BouncingScrollPhysics(),
child: Row(
children: [
InformationTile(content: "${itemData["area"]}",name: "Square Foot",),
InformationTile(content: "${itemData["bedrooms"]}",name: "Bedrooms",),
InformationTile(content: "${itemData["bathrooms"]}",name: "Bathrooms",),
InformationTile(content: "${itemData["garage"]}",name: "Garage",)
],
),
),
addVerticalSpace(padding),
Padding(
padding: sidePadding,
child: Text(
itemData["description"],
textAlign: TextAlign.justify,
style: themeData.textTheme.bodyText2,
),
),
addVerticalSpace(200),
],
),
),
Positioned(
bottom: 20,
width: size.width,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
OptionButton(text: "Message",icon: Icons.message,width: size.width*0.35,),
addHorizontalSpace(10),
OptionButton(text: "Call",icon: Icons.call,width: size.width*0.35,),
],
),
),
],
),
),
),
);
}
}
class InformationTile extends StatelessWidget{
final String content;
final String name;
const InformationTile({super.key, required this.content, required this.name});
#override
Widget build(BuildContext context) {
final ThemeData themeData = Theme.of(context);
final Size size = MediaQuery.of(context).size;
final double tileSize = size.width*0.20;
return Container(
margin: const EdgeInsets.only(left: 25),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
BorderIcon(
padding: new EdgeInsets.all(0.0),
width: tileSize,
height: tileSize,
child: Text(content,style: themeData.textTheme.headline3,)),
addVerticalSpace(15),
Text(name,style: themeData.textTheme.headline6,)
],
),
);
}
}
this is my Sample_data.dart file
in this file i add some sample data in json format
and this is how i define my DetailPage file in main.dart file
import 'package:flutter/material.dart';
import 'package:uidesign/screens/LandingPage.dart';
import 'package:uidesign/screens/DetailPage.dart';
import 'package:uidesign/utils/constants.dart';
import 'dart:ui';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
double screenWidth = window.physicalSize.width;
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Design 1',
theme: ThemeData(primaryColor: COLOR_WHITE, accentColor: COLOR_DARK_BLUE, textTheme: screenWidth < 500 ? TEXT_THEME_SMALL : TEXT_THEME_DEFAULT, fontFamily: "Montserrat"),
//home: LandingPage(),
//home: DetailPage(itemData: 1),
home: const DetailPage(),
);
}
}
error in terminal: the line i select on terminal is the error
Please help me out how it get the data with the key
Pass your RE_DATA list here in MainScreen
home: DetailPage(itemData: RE_DATA)
And Change List<dynamic> itemData to List<Map<String,dynamic>> itemData in DetailPage.
You are getting list so access itemData like this itemData[index]['image']
If possible use model for your RE_DATA instead of passing List of Maps.
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,
),
),
),
],
),
),
),
);
}
}
I want to add a scroll bar within a fixed size container in Flutter web as shown in the picture link below. Can anyone give me advice on this? I am stuck here. I have tried Single child scroll view with Flutter_web_scrollbar but it doesn't work. Here is the code.
Container(
width: 300,
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
controller: _bcontroller,
child: Column(
children: [
Container(
width: 300,
child: Row(
children: [
Text(
'${eventList.length > 0 ? i['ShipName'] : ''}',
),
],
),
),
Container(
width: 300,
child: Row(
children: [
Text(
'${eventList.length > 0 ? i[getEventDesc()].toString() : ''}',
),
],
),
),
SizedBox(
height: 10,
),
],
),
),
)
Example
Wrap SingleChildScrollView with Scrollbar Widget.
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) {
return Container(
width: 300,
height: 200,
child: Scrollbar(
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
children: [
Container(
width: 300,
height: 100,
child: Row(
children: [
Text(
'your variable',
),
],
),
),
Container(
width: 300,
height: 100,
child: Row(
children: [
Text(
'your variable',
),
],
),
),
SizedBox(
height: 10,
),
],
),),
),
);
}
}
I'm still having a bit of trouble with the layouting in Flutter.
Right now I want to have the available space shared between 3 widgets, in a quadrant layout.
The width is evenly shared (this works fine via 2 Expanded widgets in a Row), but now I also want the height to adjust automatically so widget3.height == widget1.height + widget2.height.
If the content of widget3 is larger, I want widget1 and widget2 to adjust their height and vice versa.
Is this even possible in Flutter?
Have a look at IntrinsicHeight; wrapping the root Row should provide the effect you're looking for:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(title: Text('Rows & Columns')),
body: RowsAndColumns(),
),
);
}
}
class RowsAndColumns extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(top: 100.0),
child: IntrinsicHeight(
child: Row(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
Expanded(
child: Column(children: [
Container(height: 120.0, color: Colors.yellow),
Container(height: 100.0, color: Colors.cyan),
]),
),
Expanded(child: Container(color: Colors.amber)),
]),
),
);
}
}
Adjusting the heights in the containers in the column cause the container on the right to resize to match:
https://gist.github.com/mjohnsullivan/c5b661d7b3b4ca00599e8ef87ff6ac61
I think that you can set the height of the row instead, then you only must to set the height of you column containers, and with the crossAxisAlignment: CrossAxisAlignment.stretch the second row will be expand occupying his parent height:
Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: Column(
children: [
Expanded(
// If you don't have the height you can expanded with flex
flex: 1,
child: Container(
height: 50,
color: Colors.blue,
),
),
Expanded(
flex: 1,
child: Container(
height: 50,
color: Colors.red,
),
)
],
),
),
Expanded(
child: Container(
color: Colors.yellow,
),
)
],
)
Since IntrinsicHeight is considered relatively expensive, it's better to avoid it. You can use Table with verticalAlignment: TableCellVerticalAlignment.fill in the largest TableCell.
Please note that if you use .fill in all cells, the TableRow will have zero height.
Table(children: [
TableRow(children: [
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
alignment: Alignment.center,
color: Colors.blue,
child: Text('Widget 1'),
),
Container(
alignment: Alignment.center,
color: Colors.green,
child: Text('Widget 2'),
),
],
),
TableCell(
verticalAlignment: TableCellVerticalAlignment.fill,
child: Container(
alignment: Alignment.center,
color: Colors.orange,
child: Text('Widget 3'),
)),
]),
]),
I'm new to flutter. Please correct me if I'm doing something wrong here. I think It can also be achieved using setState((){}) without using IntrinsicHeight.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return MyAppState();
}
}
class MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
double h1 = 100;
double h2 = 200;
double h3;
setState(() {
h3 = h1 + h2;
});
return MaterialApp(
home: Scaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.only(top: 100.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
children: [
Container(
color: Colors.green,
height: h1,
),
Container(
color: Colors.orange,
height: h2,
)
],
),
),
Expanded(
child: Container(
color: Colors.yellow,
height: h3,
),
)
],
),
),
),
),
);
}
}
Find image here
Code can also be found here: https://gist.github.com/Amrit0786/9d228017c2df6cf277fbbaa4a6b20e83
if you have used the expanded inside Row and facing for full height issue then just wrap the expanded child with Align widget.