In Flutter, is there an option to draw a vertical lines between components as in the image.
Not as far as I know. However, it is quite simple to create one — if you look at the source for Flutter's Divider you'll see that it is simply a SizedBox with a single (bottom) border. You could do the same but with dimensions switched.
Update (Oct 4, 2018): a VerticalDivider implementation has been merged in by the Flutter team. Check out the docs but it's very simple to use — simply put it between two other items in a row.
Note: If you are using VerticalDivider as separator in Row widget then wrap Row with IntrinsicHeight , Container or SizedBox else VerticalDivider will not show up. For Container and SizedBox widget you need define height.
As of 10 days ago, flutter has merged a VerticalDivider implementation. It will be available in the default channel very soon, but for now you have to switch to the dev channel to use it: flutter channel dev.
Here is a example of how to use it:
IntrinsicHeight(
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text('Foo'),
VerticalDivider(),
Text('Bar'),
VerticalDivider(),
Text('Baz'),
],
))
Vertical divider:
As a direct child:
VerticalDivider(
color: Colors.black,
thickness: 2,
)
In a Row:
IntrinsicHeight(
child: Row(
children: [
Text('Hello'),
VerticalDivider(
color: Colors.black,
thickness: 2,
),
Text('World'),
],
),
)
Horizontal divider:
As a direct child:
Divider(
color: Colors.black,
thickness: 2,
)
In a Column:
IntrinsicWidth(
child: Column(
children: [
Text('Hello'),
Divider(
color: Colors.black,
thickness: 2,
),
Text('World'),
],
),
)
import 'package:flutter/material.dart';
class VerticalDivider extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new Container(
height: 30.0,
width: 1.0,
color: Colors.white30,
margin: const EdgeInsets.only(left: 10.0, right: 10.0),
);
}
}
Try to wrap it inside the Container with some height as
Container(height: 80, child: VerticalDivider(color: Colors.red)),
Tried with VerticalDivider() but cannot get any divider. I Solved it with
Container(color: Colors.black45, height: 50, width: 2,),
You can use a vertical divider with a thickness of 1.
VerticalDivider(
thickness: 1,
color: Color(0xFFF6F4F4),
),
And if you can't see the vertical divider wrap the row with a IntrinsicHeight widget.
Just wrap your Row in IntrinsicHeight widget and you should get the desired result:
IntrinsicHeight(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text('Name'),
VerticalDivider(),
Text('Contact'),
],
))
As #rwynnchristian suggested, this seems to be the simplest solution IMO. Just leaving the code here:
import 'package:flutter/material.dart';
class VerticalDivider extends StatelessWidget {
#override
Widget build(BuildContext context) => RotatedBox(
quarterTurns: 1,
child: Divider(),
);
}
add this method anywhere.
_verticalDivider() => BoxDecoration(
border: Border(
right: BorderSide(
color: Theme.of(context).dividerColor,
width: 0.5,
),
),
);
now wrap your content in container
Container(
decoration: _verticalDivider(),
child: //your widget code
);
Use Container for divider is easy, wrap your row in IntrinsicHeight()
IntrinsicHeight(
child: Row(
children: [
Text(
'Admissions',
style: TextStyle(fontSize: 34),
),
Container(width: 1, color: Colors.black), // This is divider
Text('another text'),
],
),
You need to wrap VerticalDivider() widget with the IntrinsicHeight widget. Otherwise, the vertical divider will not show up. And to gain some padding over the top and bottom you can add indent.
IntrinsicHeight(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Flexible(
child: VerticalDivider(
thickness: 0.8,
color: Colors.grey,
),
),
Flexible(
child: Text(
"Random Text",
style: TextStyle(
fontSize: 12,
color: AppColor.darkHintTextColor,),
),
),
],
),
)
I guess i found a more robust solution when dealing with this problem;
IntrinsicHeight(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Container(
decoration: BoxDecoration(borderRadius: BoxRadius.circular(),color: Colors.gray),
height: 5,
margin: CustomPaddings.horizontal(),
),
),
Text(
"TEST",
style: Theme.of(context)
.textTheme
.subtitle1!
.copyWith(
color: Colors.black,
fontWeight: FontWeight.bold),
),
Expanded(
child: Container(
decoration: BoxDecoration(borderRadius: BoxRadius.circular(),color: Colors.gray),
height: 5,
margin: CustomPaddings.horizontal(),
),
),
],
),
),
Try RotatedBox in combination with a divider to get it vertical, RotatedBox is a widget of flutter that automatically rotates it's child based on the quarterTurn property you have to specify. Head over to here for a detailed explanation https://docs.flutter.io/flutter/widgets/RotatedBox-class.html
Related
Hi everyone I am new to flutter and trying to write OR in a horizontal line like shown in figure but I do not know how to do that, I have tried to google it but that did not helped me
example demonstration
Note: OR is in center
Try below Code hope its help to you. You must use this(-- OR -- ) type of design Expanded or Flexible Widget
Go here For Expanded Widget and here for Flexible Widget
Padding(
padding: EdgeInsets.all(8.0),
child: Row(
children: [
Expanded(
child: Divider(
color: Colors.black,
thickness: 1,
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('OR'),
),
Expanded(
child: Divider(
color: Colors.black,
thickness: 1,
),
),
],
),
),
Your result Screen like ->
Below is the solution using a row widget
Row(children: const [
Expanded(child: Divider(thickness: 1.5)),
Text("OR",
style: TextStyle(fontSize: 20, color: Colors.grey)),
Expanded(child: Divider(thickness: 1.5)),
]),
This is it when i tried to create Instagram login screen
I'm building a product detail page. As the following piece of code and image shown, when there is a lot of content in the description part, the bottom overflow will occur. I'm wondering how to make the page scrollable, I've tried wrapping the Stack with SingleChildScrollView, but this is definitely not working in my case here. Can anyone help me with that? Thank you very much!!!!!
class DetailsScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
return Scaffold(
backgroundColor: Colors.white,
body: Stack(
children: [
buildBody("path/to/image", size),
],
),
);
}
Positioned buildBody(String imagePath, Size size) {
return Positioned.fill(
child: Column(
children: [
Expanded(
child: Container(
padding: EdgeInsets.symmetric(vertical: 60, horizontal: 30),
color: Colors.green,
child: Stack(
children: [
Align(
alignment: Alignment.center,
child: Hero(
tag: 1,
child: Image.asset(
imagePath,
width: size.width * 0.7,
),
),
),
],
),
),
),
Expanded(
child: Container(
color: Colors.white,
child: Column(
children: [
SizedBox(
height: 100,
),
Container(
margin: EdgeInsets.symmetric(
horizontal: 20,
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CircleAvatar(),
SizedBox(
width: 10,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Anvesha Shandilya',
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 16),
),
Text(
'Owner',
style: TextStyle(
color: fadedBlack,
),
),
],
),
Expanded(child: Container()),
Text(
'Dec 16, 2020',
style: TextStyle(
color: fadedBlack,
fontSize: 12,
),
),
],
),
),
SizedBox(
height: 30,
),
Container(
margin: EdgeInsets.symmetric(
horizontal: 20,
),
child: Text(
'A lot of content..................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................',
style: TextStyle(
color: fadedBlack,
height: 1.7,
),
),
),
],
),
),
),
],
),
);
}
}
Error: Bottom Overflowed
To reproduce: Change the path/to/image, to this: A image can be used with the code:
tl;dr remove Expanded widgets -> remove Stack -> replace Column with ListView (for scrollability)
Start by removing Expanded widgets from the tree as you don't really need them. If possible, you should use mainAxisAlignment and crossAxisAlignment to position your widgets. That's exactly how you should handle placing the date next to user's name.
Expanded documentation states with which widgets you can use it:
Creates a widget that expands a child of a Row, Column, or Flex so
that the child fills the available space along the flex widget's main
axis.
Then remove Stack widget. If you don't then it will still work as Stack tries to get as big as its positioned children so it will just get as big as the Column you have inside. It's redundant.
Last but not least, replace Column with ListView. Column doesn't really care about whether it's overflowing or if it's being rendered. So if you create a Column that is bigger than the screen, it will simply display it which will cause the overflow. To fix that you could wrap it SingleChildScrollView, but I think it's more appropriate to just use ListView instead.
Here's an amazing explanation of layout system in Flutter: https://flutter.dev/docs/development/ui/layout/constraints
In HTML creating a page that is divided into 2 columns that span 100% of the screen height is easy
<div id="row">
<div id="column1" style="width:75%; height:100%"></div>
<div id="column2" style="width:25%; height:100%"></div>
</div>
Using Flutter this seems more complicated than it should be, i tried to achieve the above in a couple of ways: (The page's outline is CustomScrollView -> SliverToBoxAdapter -> Row -> Columns)
Using MediaQuery to set the columns' height as deviceSize.height. This failed because as the left column got bigger than the right column, the right column did not expand in size to match.
Using Expanded or Flexible (tight or loose) to try and expand the height. This did not work.
My question is how do i achieve 100% height and not 100vh height in Flutter web?
Edit:
This illustrates the problem, the right column is not expanding in size to match the left column.
CustomScrollView(
slivers: <Widget>[
SliverFillRemaining(
child: Container(
color: Colors.purple,
child: SingleChildScrollView(
child: Row(
children: <Widget>[
Container(
color: Colors.blue,
child: Column(
children: <Widget>[
Text("test"),
SizedBox(height: 300),
Text("test"),
SizedBox(height: 300),
Text("test"),
SizedBox(height: 300),
Text("test"),
SizedBox(height: 300),
],
),
),
Container(
color: Colors.yellow,
child: Column(
children: <Widget>[Text("test")],
),
),
],
),
),
),
),
],
);
Not sure if this is what you want. But based on your statement I think you are looking for two column layout as in here and as shown below in the image.
Following is the code for the same. You can adjust the flex value in the Expanded widget to acquire the required screen width ratio. but if you want to adjust the width each columns like using a drag handle or so, then this alone wont suffice.
import 'package:flutter/material.dart';
class FullHeightDemo extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
child: Row(
children: <Widget>[
Expanded(
flex: 4,
child: Container(
color: Colors.red,
child: Center(
child: Text(
'Column-1',
style:
TextStyle(fontWeight: FontWeight.bold, color: Colors.black),
),
),
),
),
Expanded(
flex: 1,
child: Container(
child: Container(
color: Colors.teal,
child: Center(
child: Text(
'Column-2',
style: TextStyle(
fontWeight: FontWeight.bold, color: Colors.black),
),
),
),
),
)
],
));
}
}
Specifying the height using MediaQuery inside a Scrollable widget could help
Following code places the columns inside a SingleChildScrollableView widget and specifies the height of the container based on MediaQuery to achieve the same. Will this help.? The LayoutBuilder is only there to show that the using the height from its constraints could also lead to error since in this case its height is also infinite.
import 'package:flutter/material.dart';
class FullHeightDemo extends StatelessWidget {
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: LayoutBuilder(
builder: (context, constraints) {
var size = MediaQuery.of(context).size;
return Container(
child: Row(
children: <Widget>[
Container(
height: size.height,
// height: constraints.maxHeight,
width: constraints.maxWidth / 2,
color: Colors.red,
child: Center(
child: Text(
'Column 1',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
),
),
Container(
color: Colors.green,
height: size.height,
// height: constraints.maxHeight,
width: constraints.maxWidth / 2,
child: Center(
child: Text(
'Column 2',
style: TextStyle(
fontWeight: FontWeight.bold, color: Colors.black),
),
),
)
],
),
);
},
),
);
}
}
I need a Container with some text in to auto expand. I have an API call, which can be anything from 5 words to 500 words. I don't want to just have 1 fixed size that's huge, but contains 10 words.
I have tried Expanded() and SizedBox.Expand(), but I might be using them wrong
Card(
elevation: defaultTargetPlatform ==
TargetPlatform.android ? 5.0 : 0.0,
child: Column(
children: <Widget>[
Container(
margin: const EdgeInsets.all(0.0),
padding: const EdgeInsets.all(2.0),
decoration: BoxDecoration(color: Colors.black),
width: _screenSize.width,
height: 250,
child: Column(
children: <Widget>[
Container(
color: Colors.black,
width: _screenSize.width,
height: 35,
child: Padding(
padding: const EdgeInsets.only(
left: 15, top: 11),
child: Text("Title".toUpperCase(),
style: TextStyle(
color: Colors.white
),
),
),
),
Container(
color: Colors.white,
width: _screenSize.width,
height: 210,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 8, bottom: 5),
child: Text("Title of expanding text", style: TextStyle(
fontSize: 25,
),
),
),
Text("Expanding text", style: TextStyle(
fontSize: 35,
fontWeight: FontWeight.w800
),),
],
),
),
],
),
),
],
),
),
I just need the Container to expand, but stay small/get bigger
Have you tried not specifying height at all? The Container should wrap according to the child in this case.
Otherwise, the widget has a child but no height, no width, no
constraints, and no alignment, and the Container passes the
constraints from the parent to the child and sizes itself to match the
child.
Above is an extract from the official flutter documentation for Container.
Here is the official flutter documentation link.
You can use FittedBox, this will resize your text according to available area.
You can use it like this :
FittedBox(child: Text('...............Your text...............'));
I would suggest you to use Constraints...this will set Container height according to the Text child's requirement. Please see the example...
Container(
constraints: BoxConstraints(
maxHeight: double.infinity,
),
child: Column(
children: [
Text(
'Hello flutter...i like flutter...i like google...',
softWrap: true,
style: TextStyle(
color: Colors.white, fontSize: 20 , ),
),],),)
we just neeed to add mainAxisSize: MainAxisSize.min, properties inside child Column or Row where the child is set to Container
for example
AnythingYourWidget(
child: Container(
child: Column( // For Example Column
mainAxisSize: MainAxisSize.min, // these properties following the children content height available.
children: [
// YourWidget
]
)
)
),
I too had a container with a text widget inside that would not scale as the text increased in character count. Make the widget tree Container -> IntrinsicWidth -> Text/TextField and it seems to play nicely for me.
IntrinsicWidth will scale the size of the container to its child.
I have a stack widgets with two widgets inside.
One of them draws the background, the other one draws on top of that.
I want both widgets to have the same size.
I want the top widget, which is a column, to expand and fill the stack vertically to the size that is set by the background widget.
I tried setting the MainAxis mainAxisSize: MainAxisSize.max but it didn't work.
How can I make it work?
Use Positioned.fill
Stack(
children: [
Positioned.fill(
child: Column(
children: [
//...
],
),
),
//...
],
);
More info about Positioned in Flutter Widget of the Week
How does it work?
This is all about constraints. Constraints are min/max width/height values that are passed from the parent to its children. In the case of Stack. The constraints it passes to its children state that they can size themselves as small as they want, which in the case of some widgets means they will be their "natural" size. After being sized, Stack will place its children in the top left corner.
Positioned.fill gets the same constraints from Stack but passes different constraints to its child, stating the it (the child) must be of exact size (which meant to fill the Stack).
Positioned.fill() is the same as:
Positioned(
top: 0,
right: 0,
left: 0,
bottom:0,
child: //...
)
For even more examples and info: How to fill a Stack widget and why? and Understanding constraints.
You can try wrapping the Column with a positioned widget. Set top to 0 and bottom to 0. This will make the column fill the stack vertically.
sample code:
Stack(
children: <Widget>[
// Background widget rep
Container(
color: Colors.pink,
),
Positioned(
top: 0,
bottom: 0,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('madonna'),
Text('flutter'),
],
),
)
],
)
I think you could wrap you column in a container like this:
Container(
height: double.infinity,
width: double.infinity,
child: Column()
),
The accepted answer did not answer my issue completely. So, I put my code here in case you have a similar issue.
class NoContentView extends StatelessWidget {
const NoContentView({Key? key, required this.message}) : super(key: key);
final String message;
#override
Widget build(BuildContext context) {
return Expanded(
child: Stack(
children: [
Positioned.fill(
child: FittedBox(
child: const Image(image: AssetImage(AppImages.noReceiptsWeb), fit: BoxFit.fitWidth),
),
),
MessageView(message: message),
],
),
);
}
}
In my case, I thought that I needed to expand the container in the light blue color with an expanded widget inside the stack widget.
Problems arose, especially since I was adding the stack widget in the column widget, and the way to make the container double.infinity dimensions I definitely had a problem with the vertical axis.
In the end, I managed to show it like this photo...
Column(
children: [
//filter
Container(
color: orange,
height: 50,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(20, 0, 20, 0),
child: Text(
'All',
style: getRegular(color: white.withOpacity(.6)),
),
),
Container(
color: white.withOpacity(.6),
width: 1,
height: 50,
),
Padding(
padding: const EdgeInsets.fromLTRB(20, 0, 10, 0),
child: Text(
'Ready',
style: getRegular(color: white.withOpacity(.6)),
),
),
freeh(),
Container(
color: white.withOpacity(.6),
width: 1,
height: 50,
),
],
),
Row(
children: [
Icon(
filter,
color: white.withOpacity(.7),
size: 20,
),
Text(
'FILTER',
style: getLight(
color: white.withOpacity(.7),
),
),
freeh(),
],
),
],
),
),
Expanded(
child: Stack(
alignment: Alignment.topLeft,
children: [
Container(
color: lightBlue, //here to use map>>>>
),
Container(
height: 35,
width: 120,
margin: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: primary,
borderRadius: BorderRadius.circular(20),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Icon(
FontAwesomeIcons.listUl,
color: white.withOpacity(.8),
size: 20,
),
Text(
'List View',
style: getRegular(color: white.withOpacity(.8)),
)
],
),
),
],
),
)
],
),