I am trying to create a Draft Page Screen for a blog app ,which has a Textfield and a close icon for closing it and a Publish Text for publishing it .I have given the Publish a Close icon in a row so even if scroll down after typing the row should remain fixed at the top .But how can I make the row widget fixed at the top of the body ?
This is my code:
ListView(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
InkWell(
child: Icon(Icons.close_sharp),
onTap: () {
Navigator.pop(context);
},
),
Text("Publish"),
],
),
TextField(
autofocus: true,
decoration: new InputDecoration(
border: InputBorder.none),
keyboardType: TextInputType.multiline,
maxLines: null,
cursorColor: Color(0xff057009),
cursorHeight: 30,
),
],
),
Try this code this will do the trick.
Scaffold(
appBar: AppBar(
title: const Text('Blog View'),
),
body: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
InkWell(
child: const Icon(Icons.close_sharp),
onTap: () {
Navigator.pop(context);
},
),
const Text("Publish"),
],
),
const Expanded(
child: TextField(
autofocus: true,
decoration: InputDecoration(border: InputBorder.none),
keyboardType: TextInputType.multiline,
maxLines: null,
cursorColor: Color(0xff057009),
cursorHeight: 30,
),
),
],
),
);
Your row must be outside the list. You can make the list scrollable as well, but just make it outside the main list.
Here is an example:
Column with a preferred height, for example media query . size . height - > [
SizedBox height: the height you want to show of the row
-> SingleChildScrollView -> your Row with the possibly overflowing text
...Your other children in a scrollable view
]
Related
I am using a row, inside it, each text is a column and I want that whenever my text overflows, it should automatically go to next line, I tried everything, but it won't work. When I tried to use expanded or flexible, it gave error. I tried to make maxlines 2 and then use expanded/flexible, I also gave it a container as a parent widget and made it's height big enough, still error.
Here is the code snippet -
class RouteItems extends StatelessWidget {
final int index;
final NodeElement data;
RouteItems({required this.index, required this.data});
#override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Column(
children: [
SvgPicture.asset(
'assets/icons/road-straight-line-top-view.svg',
height: 15,
width: 80,
),
SvgPicture.asset(
filterRoutesIcon("${data.node?.type}"),
height: 30,
width: 30,
),
SvgPicture.asset(
'assets/icons/road-straight-line-top-view.svg',
height: 15,
width: 80,
),
],
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: Container(
//height: 60,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text(
'${data.node?.name}',
style: TextStyle(fontSize: 12.0),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
],
),
Text(
data.eta!.getFormattedDate('hh:mm a, d MMM'),
style: TextStyle(fontSize: 10.0, color: colorDarkGrey),
)
],
),
),
),
],
),
Align(
alignment: Alignment.centerRight,
child: Icon(
Icons.timer,
),
),
],
);
}
}
This Row can be removed, what is the purpose of it ?
Row(
children: [
Text(
'${data.node?.name}',
style: TextStyle(fontSize: 12.0),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
],
)
You can try removing the maxLines: 1, and adding width constraints to your Text e.g wrapping it with a SizedBox, this way the text will wrap to the next line :
SizedBox(
width: 200,
child: Text(
'${data.node?.name}',
style: TextStyle(fontSize: 12.0),
),
)
Try below code hope its helpful to you. Just wrap your Text widget inside Expanded of Flexible
Refer Expanded here
Refer Flexible here
Or
Try to add your Inside Row widgets wrap it with Expanded or Flexible refer my answer here or here or here hope its helpful to you
Row(
children: [
Expanded(
child: Text(
'{data.node?.name}{data.node?.name}{data.node?.name}{data.node?.name}'
'{data.node?.name}{data.node?.name}{data.node?.name}{data.node?.name}'
'{data.node?.name}{data.node?.name}{data.node?.name}{data.node?.name}'
'{data.node?.name}{data.node?.name}',
style: TextStyle(fontSize: 12.0),
),
),
],
),
Your result Screen->
Try wrapping the text you want to not overflow in a Flexible() widget. That will make sure it doesn't take up more space in the row than is available.
You can also add or replace width paramater of SizedBox widget with
width: MediaQuery.of(context).size.width,
to constraint the Text child to the device screen width.
You can try this aproach
Expanded(
Row(
children: [
Card(
child: Text(" My awseome no overflow text"),),
..Other Widgets
]
),
);
I'm trying to develop a Card with some text widget beneath it. Look at the image below.
The problem I'm facing is when the text next to location icon is large, it overflows. I've tried with Flex, but it throws an exception. There's also a star icon at the right bottom of the card.
Here's what I want :
I want the text to be single line ending with .. if it's too long.
star should be placed at the bottom right
The location icon doesn't consider the left padding I gave (Padding widget)
Please help! Thanks in advance.
Here's my code :
Scaffold buildOffersList(OfferModel offerModel) {
return Scaffold(
body: Stack(
children: <Widget>[
Center(
child: Image.network(
'https://b.zmtcdn.com/data/pictures/2/19250332/0fe23bee17b60d181fd43421ca3480d4_featured_v2.jpg',
fit: BoxFit.cover,
width: size.width,
height: size.height,
color: Colors.black.withOpacity(.6),
colorBlendMode: BlendMode.darken
),
),
Column(
children: <Widget>[
Container(
child: PageHeader(pageTitle: 'Popular Offers', numberOfOffers: '20 venues', sortByText: 'Sort By: Location', filterText: 'Filter'),
),
Expanded(
child: GridView.count(
crossAxisCount: 2,
mainAxisSpacing: 5.0,
crossAxisSpacing: 5.0,
padding: const EdgeInsets.only(left: 10.0, right: 10.0),
children: List.generate(offerModel.payload.offers.length, (index) {
return Center(
child: offerCard3(offerModel.payload.offers[index]),
);
}),
),
),
],
),
],
)
);
}
Widget offerCard3(Offer offer) {
return GestureDetector(
child: Card(
elevation: 1.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0.0),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
AspectRatio(
aspectRatio: 18.0 / 8.0,
child: Image.network(
"https://b.zmtcdn.com/data/pictures/2/19250332/0fe23bee17b60d181fd43421ca3480d4_featured_v2.jpg",
fit: BoxFit.cover,
),
),
Padding(
padding: EdgeInsets.fromLTRB(7.0, 5.0, 4.0, 5.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
getBrandName(offer),
getOfferTitle(offer),
SizedBox(height: 15.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
getLocationIcon(),
getOfferContactAddressView(offer),
],
),
getKmText(),
],
),
//Spacer(),
getStarIcon(),
],
),
],
),
),
],
),
),
);
}
Text getOfferContactAddressView(Offer offer) {
return Text(
offer.offerContactAddress,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Colors.black38,
fontSize: 9.0,
),
);
}
Icon getStarIcon() {
return Icon(
Icons.star,
color: Colors.orange,
size: 25,
);
}
There is a flutter package for auto resize text to contain the full text.
auto_size_text 2.1.0 here
FIrst Solution Highly Recommend
First of all, you can use Listtile.
ListTile(title: Text("ListTile"),
subtitle: Text("Sample Subtitle. \nSubtitle line 3"),
trailing: Icon(Icons.home),
leading: Icon(Icons.add_box),
isThreeLine: true,
)
Second Solution
SizedBox(
width: 500,
child: new Text(
'Text largeeeeeeeeeeeeeeeeeeeeeee',
//Overflow: TextOverflow.ellipsis will make you large text end with ....
overflow: TextOverflow.ellipsis,
style: new TextStyle(
fontSize: 13.0,
),
),
),
I think you have to use like below code:-
Expanded(
child: Wrap(
direction: Axis.horizontal,
runAlignment: WrapAlignment.start,
children: <Widget>[
getOfferContactAddressView(offer),
],
),
flex: 1,
),
It happens because the Text Widget doesn't know how big the width of the Row.
Please try this code out DartPad to help you find where you went wrong with your code. I still believe, wrapping the Text Widget with Expanded and give overflow property will give what you want right away.
Here's the SS of it:
I am trying to center Two elements in a Row widget that resides in a Colum widget. The last Row in this code is of interest. I have noticed that when I remove the "Flexible(...)" widget from that Row, then the Text centers horizontally. Otherwise, both elements stick to the left-hand side of the screen. I want both of the elements to stick to the center. I tried wrapping the Flexible widget into a Container and then Aligning that container to the middle, Flutter did not like that.
I am looking for the Two widgets in the last row to center horizontally
void main() => runApp(MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Example 1"),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
child: Center(
child: ButtonBar(
children: <Widget>[
RaisedButton(
child: Text("Button"),
),
RaisedButton(
child: Text("Button"),
)
],
),
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Container(
child: Center(
child: ButtonBar(
children: <Widget>[
RaisedButton(
child: Text("Button"),
),
RaisedButton(
child: Text("Button"),
)
],
),
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("Email:"),
Flexible(
child: TextField(
textAlign: TextAlign.justify,
decoration: InputDecoration(
border: InputBorder.none,
hintText: "Enter Email",
),)),
],
),
],
),
floatingActionButton: FloatingActionButton(
child: Text("clock"),
),
),
));
A Row Widget will try to use as much space as possible (https://api.flutter.dev/flutter/widgets/Row-class.html)
if you wrap your children widgets inside a Flex and centre the Main Axis, you will see the children elements centred
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Flexible(
flex: 1,
child: Text("Email:"),
),
Flexible(
flex: 1,
child: TextField(
textAlign: TextAlign.justify,
decoration: InputDecoration(
border: InputBorder.none,
hintText: "Enter Email",
),
),
),
],
),
I know that we can use a ListView or Expanded instead of column in such case , but when I use ListView instead of Column , I get a runtime exception for the below code .
The TextFields in the column overflow when the keyboard opens after focusing an input .
class _AddAchievementDialog extends State<AddAchievementDialog> {
String title, description, longDescription, linksString, id;
List<String> links;
#override
Widget build(BuildContext context) {
return AlertDialog(
title: Text(
"Add",
textAlign: TextAlign.center,
),
shape: RoundedRectangleBorder(),
contentPadding: EdgeInsets.all(10),
content: Container(
padding: EdgeInsets.all(10),
height: 350,
child: Column(
children: <Widget>[
TextField(
decoration: InputDecoration(labelText: 'Title'),
),
TextField(
keyboardType: TextInputType.multiline,
maxLines: 2,
decoration: InputDecoration(labelText: 'Description'),
),
TextField(
keyboardType: TextInputType.multiline,
maxLines: 3,
decoration: InputDecoration(labelText: 'Long Description'),
),
TextField(
decoration:
InputDecoration(labelText: 'Links (seperated by comma) '),
),
],
),
),
actions: <Widget>[
RaisedButton(
child: Text("Submit"),
)
],
);
}
}
You have to wrap the Column-Widget inside aScrollView- Widget and adjust some flagsit.
ListView(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
children: <Widget>[
Text();
]
);
With those set, you prevent your Widget from showing the overflow- error; furthermore, with the physics set, you prevent the listview from showing the overscroll-ui inside the listview.
I'm building a flutter app with a Login Screen. On focus on the text field(s), the screen is overflowed and i cannot scroll. I've tried using a ListView.builder, but that just gives a renderBox error, and the regular ListView doesn't work
The widget structure is like this
-scafold
- body
- container
- column
- form
- column
- textInput
- textInput
- container
- container
- row
- raisedButton
Thank You in advance !!
The ListView solution should work, but at the time of writing, it suffers from the crash listed here. Another way to achieve the same thing without this crash is to use a SingleChildScrollView:
return new Container(
child: new SingleChildScrollView(
child: new Column(
children: <Widget>[
_showChild1(),
_showChild2(),
...
_showChildN()
]
)
)
);
try this Code: Its Using ListView
class Home extends StatelessWidget {
#override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
body: Center(
child: ListView(
shrinkWrap: true,
padding: EdgeInsets.all(15.0),
children: <Widget>[
Center(
child: Card(
elevation: 8.0,
child: Container(
padding: EdgeInsets.all(10.0),
child: Column(
children: <Widget>[
TextField(
decoration: InputDecoration(
prefixIcon: Icon(Icons.person),
labelText: "Username or Email",
),
),
SizedBox(
height: 15.0,
),
TextField(
decoration: InputDecoration(
prefixIcon: Icon(Icons.lock),
labelText: "Password",
),
),
SizedBox(
height: 15.0,
),
Material(
borderRadius: BorderRadius.circular(30.0),
//elevation: 5.0,
child: MaterialButton(
onPressed: () => {},
minWidth: 150.0,
height: 50.0,
color: Color(0xFF179CDF),
child: Text(
"LOGIN",
style: TextStyle(
fontSize: 16.0,
color: Colors.white,
),
),
),
)
],
),
),
),
),
SizedBox(
height: 25.0,
),
Row(
children: <Widget>[
Expanded(child: Text("Don't Have a Account?")),
Text("Sign Up",
style: TextStyle(
color: Colors.blue,
)),
],
),
],
),
),
bottomNavigationBar: Padding(
padding: EdgeInsets.all(10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: RaisedButton(
padding: EdgeInsets.all(15.0),
onPressed: () {},
color: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
32.0,
),
side: BorderSide(color: Color(0xFF179CDF))),
child: Text(
"SKIP SIGN UP FOR NOW",
style:
TextStyle(fontSize: 18.0, color: Color(0xFF179CDF)),
),
)),
],
),
),
);
}
}
There are two easy ways of doing it.
Wrap your Column in a SingleChildScrollView
SingleChildScrollView(
child: Column(
children: [
Text('First'),
//... other children
Text('Last'),
],
),
)
Use ListView instead of Column.
ListView(
children: [
Text('First'),
//... other children
Text('Last'),
],
)
This approach is simple to use, but you lose features like crossAxisAlignment and other benefits provided by Column, in that case, you can wrap your children widget inside Align and set alignment property.
Now you may have nested children which are further scrollable, in that case, you need to provide a fixed height to your children, you may use SizedBox for that, that's it.
For example:
ListView(
children: [
Text('First'),
SizedBox(
height: 100,
child: ListView(...), // nested ScrollView
),
Text('Last'),
],
)
We can use the Expanded widget. It will add scrolling.
return new Expanded(
child: new SingleChildScrollView(
child: new Column(
children: <Widget>[
_showChild1(),
_showChild2(),
...
_showChildN()
]
)
)
);
Wrap your column in SingleChildScrollView and then wrap SingleChildScrollView in a Center widget to center the widgets in the column.
Center(
child: SingleChildScrollView(
child: Column(
children: [
Text('First'),
//... other children
Text('Last'),
],
),
)