It's hard to explain what I want. So I will try to explain with an example:
Now I have a Card() And I have a ListView() and Card' s height is 100
Now I want to move the ListView off the Card
Image example:
note: I can have other widgets in Card. for example:
Card(
child : Column(
[
Text('abc'),
PopUpListView(),
])
)
I'm sorry about my bad English :(
You can use a Stack() widget. Try this snippet.
Stack( children: [ Card(), ListView(), ], )
I could not get what do you mean but If you want to place a listview in a card height 100 you can use following code snippet;
Container(
height: 100,
color: Colors.red,
child: Card(
child: ListView(
children: [
Text(widget.title),
Text(widget.title),
Text(widget.title),
],
),
),
)
Related
I have this design, The first section in the red box is fixed height size, and The second section is the dynamic height (ListviewBuilder) which changed the content based on the tabBar.
My question is How can I use the TabBar view inside the scrollable widget (custom scroll view/listview etc..)
the solution That I currently found is to use a customScrollView and use SliverFillRemaining like that
SliverFillRemaining(
child: TabBarView(
children: [],
),
),
but that adds extra white space at the bottom of the list and I can't remove it by
making hasScrollBody property false
You could probably achieve what you want with this kind of template :
Scaffold(
body: Column(
children: [
Container(
height: MediaQuery.of(context).size.height * .33,
child: Container(/* Content of the first section */),
),
Expanded(
child: DefaultTabController(
length: 2,
child: CustomScrollView(
slivers: [
SliverToBoxAdapter(
child: Container(
height: 50,
child: TabBar(
tabs: [Text("Guest"), Text("Service")],
),
),
),
SliverFillRemaining(
child: TabBarView(
children: [
// Your ListView Builder here
],
),
),
],
),
),
),
],
),
);
Seeing the bit of code you posted, it is probably close to what you already have but after test it doesn't adds extra white space at the bottom.
If it continue to display the same behavior, adding a little more context could help us provide a more accurate answer.
I want to make my screen into 3 equal part using container class in flutter. How to do that?
What you want is the Flexible widget
Let's say you want the three equal parts to be stacked vertically
return Column(
children: [
Flexible(child: Container()),
Flexible(child: Container()),
Flexible(child: Container()),
]
);
You can also specify a flex component to signify the relationship between the widgets' sizes
return Column(
children: [
Flexible(child: Container(), flex:1),
Flexible(child: Container(), flex:2),
]
);
which will make the second widget take 2/3 of the available space
I prefer using LayoutBuilder, it constraints that can be used to get body height,maxWidth, also it provides more than this. Also, you can try media query.
#override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
return Scaffold(
body: LayoutBuilder(
builder: (context, constraints) => Column(
children: [
Container(
height: constraints.maxHeight / 3,
width: constraints.maxWidth,
color: Colors.deepPurple,
),
Container(
height:size.height/3,
width: size.width/3,
color: Colors.deepPurple,
)
],
),
));
}
You can remove Column it's just an example. Using LayoutBuilder provide parents' constraints.
I have widget:
Scaffold(
appBar: ...,
body: Form(
child: ListView(
children: [
...
ElevatedButton() // Save button
]
)
)
);
So, I want to place it to the bottom of the screen. I tried to place it inside Align widget but it doesn't work. Another thing is that I have ExpansionTile above and it can overflow the screen. In this case, there mustn't be any additional space between Activate and Save buttons. How to do it?
Use MainAxisAlignment.spaceBetween. Documentation:
Place the free space evenly between the children.
bool _hasExpansionTile = false;
Scaffold(
appBar: ...,
body: Column(mainAxisAlignment: _hasExpansionTile ? MainAxisAlignment.start : MainAxisAlignment.spaceBetween, /// Checking that the expansion tile is visible
children: [
Flexible(
child: Form(
child: Column(
children: [
...
],
),
),
),
ElevatedButton(onPressed: (){}, child: Text("Send")),
],
),
);
Of course you must use setState(), when you changing the value of the _hasExpansionTile property.
You can use Spacer()
Scaffold( appBar: ...,
body: Form(
child: ListView(
children: [
...
Spacer(),
ElevatedButton() // Save button
]
)
)
);
I need to fix a minimum width to my Column Widgets. Inside each of them, I have Text Widgets which can be very short or very long. I need to fix a minimum width to them in order to have an acceptable size of Column even if the text is short. The other Column need obviously to adapt himself.
Row(children: [
Column(
children: [
Container(
constraints: BoxConstraints(minWidth: 80), // do not work
child: Text("short text"),
),
],
),
Column(
children: [
Container(
constraints: BoxConstraints(minWidth: 110), // do not work
child: RichText(
text: TextSpan(
text:"very very longggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg text")),
),
],
),
],
)
There's probably a dozen ways to do what you want. And likely none of them straightforward or easy to understand. (The subject of constraints & sizes is quite complicated. See this constraints page for more examples & explanations.)
Here's one potential solution.
This will set a minimum width for the blue column (based on stepWidth), but will expand/grow if the text (child) inside wants to.
The yellow column will resize to accommodate the blue column.
class ExpandedRowPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Expanded Row Page'),
),
body: SafeArea(
child: Center(
child: Row(
children: [
IntrinsicWidth(
stepWidth: 100,
// BLUE Column
child: Container(
color: Colors.lightBlueAccent,
child: Column(
children: [
//Text('Short'),
Text('shrt')
],
)
),
),
// YELLOW Column
Flexible(
child: Container(
alignment: Alignment.center,
color: Colors.yellow,
child: Column(
children: [
Text('Very lonnnnnnnnnnnnnnnnnnnnnnnnnnnng texttttttttttttt'),
],
)
),
)
],
)
),
),
);
}
}
You could do the above without a Flexible yellow column, but a very long text child would cause an Overflow warning without a Flexible or Expanded wrapping widget.
A Row widget by itself has an infinite width constraint. So if a child wants to be bigger than screen width, it can, and will cause an overflow. (Try removing Flexible above and rebuild to see.)
Flexible and Expanded, used only inside Row & Column (or Flex, their superclass), checks screen width and other widgets inside a Row, and provides its children with a defined constraint size instead of infinite. Children (inside Flexible/Expanded) can now look up to parent for a constraint and size themselves accordingly.
A Text widget for example, will wrap its text when it's too wide for constraints given by Flexible/Expanded.
use FittedBox();
suppose Example:
Row(
children: [
Column(
children: [
Container(
constraints: BoxConstraints(minWidth: 80), // do not work
child: Text("short text"),
),
],
),
Column(
children: [
Container(
constraints: BoxConstraints(minWidth: 110), // do not work
child:
FittedBox(
child: RichText(
text: TextSpan(
text:
"very very longggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg text")),
),
),
],
),
],
);
I would like to have a static bottom bar for my app.
This bar should content the hour of a device in the middle, and the temperature read by another device on the right side.
My problem is just about the positioning/sizing.
When I start it (with android studio, on real or virtual device), it doesn't work : the preview is not what I excepted, the dimensions I choose seem to have changed.
But when I hot-reload it, it becomes exactly what I want like this :
The problem is that the final app is not the hot-reloaded one ..
I may have identify the problem,
I use a MediaQuery.of(context).size and a builder to obtain the context in order to fit with all the devices considering the size. This solution must be a dirty one but I don't find anything else..
Here is my code, hope the situation is clear...
return new MediaQuery(
data: MediaQueryData.fromWindow(ui.window),
child: Builder(
builder: (context) {
return new Builder(
builder: (
context) {
return
new MaterialApp(
home: new DefaultTabController(
length: 6,
child: Scaffold(
bottomNavigationBar:
new Container(
color: Colors.white,
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height*0.1,
alignment: Alignment.centerRight,
child: new Container(
color: Colors.blue,
width: MediaQuery.of(context).size.width* 2/3,
alignment: Alignment.centerRight,
child: new Row(
children: <Widget>[
new Expanded(child: new Container(
color : Colors.yellow,
child: new Text('22 : 22' ),
alignment: Alignment.center,
)),
new Expanded(child:new Container(
color: Colors.pink,
child: new Text(' 37.8 °C'),
margin: new EdgeInsets.all(MediaQuery.of(context).size.width*0.02),
alignment: Alignment.centerRight,
))
],
),
),
),
Thank you for helping.
You could use a Stack and position one of the widget absolute over the other one:
new Stack(
children: <Widget> [
new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget> [
new Text(time),
],
),
new Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget> [
new Text(temperature)
],
),
],
),
where time & temperature are variables that were set within the state (Stateful Widgets). Then just include it in bottomNavigationBar.
I eventually added my previous code in a StatelessWidget and call it in the bottomNavigationBar field of the Scaffold : it does the job.
And I call MediaQuery.of(context) within the StatelessWidget created
Thank you.