I have a situation where I need to wrap text with an input in Flutter. An example: 'The cat goes <TextField>, the dog goes bark.'
I'm using the Row class to format it this way, however, the row class doesn't wrap text.
Widget _buildQuestionText(String sentence) {
List splitSentence = sentence.split('\$guess');
return new Container(
child: Row(
children: <Widget>[
new Text(splitSentence[0]),
new Expanded(child: new TextField()),
new Text(splitSentence[1]),
]
),
);
}
Which creates:
I have looked at using the Flex class but was unable to achieve the format I wanted. How can I achieve text wrapping with an input in the middle of text?
Wrap accepts a list of children that wraps while row accepts a list of children that do not wrap.
return new Container(
child: new Wrap(
spacing: 8.0, // gap between adjacent chips
runSpacing: 4.0, // gap between lines
children: [
new Text(splitSentence[0]),
new Container(
width: 100.0,
child: new TextField(
style: new TextStyle(
fontSize: 16.0,
color: Colors.black
)
)
),
new Text(splitSentence[1]),
],
)
);
Related
I want my body to be scrollable with this code below i included and image of what is is now
I need help in getting this thing to work
any opinions
to get a better idea
it is an e-commerce app with a carousel then below it categories and the below them the products
i need scrolling to be as if all of this is on part
how?
body: new Column(
children: <Widget>[
// ================= IMAGE CAROUSEL BEGINS HERE ==================
new ImageCarouselUI(),
// ================= HORIZONTAL LIST SECTION ====================
//padding widget
new Padding(padding: const EdgeInsets.all(6.0),
child: Container(
alignment: Alignment.centerLeft,
child: new Text('Categories', style: new TextStyle(fontSize: 15.0),)),
),
//Horizontal list view begins here
HorizontalList(),
//padding widget
new Padding(padding: const EdgeInsets.all(10.0),
child: new Container(
alignment: Alignment.centerLeft,
child: new Text('Recent products')),),
//grid view
new Flexible(
child: Products()
),
],
),
Image Of What I Want It to be:
If all your body is only one complex widget you can use use a SingleChildScrollView class.
//...
body: SingleChildScrollView ( // this will make your body scrollable
child: Column(
/// your parameters
children: <Widget> [
// your widgets,
// your widget...
],
),
)
,
This question already has answers here:
Flutter - Wrap text on overflow, like insert ellipsis or fade
(23 answers)
Closed 3 years ago.
I want wrap text as text grows. I searched through and tried wrap with almost everything but still text stays one line and overflows from the screen.
Does anyone know how to achieve this?
Any help is highly appreciated!
Positioned(
left: position.dx,
top: position.dy,
child: new Draggable(
data: widget.index,
onDragStarted: widget.setDragging,
onDraggableCanceled: (velocity, offset) {
setState(() {
position = offset;
widget.secondCallback(offset, widget.index);
widget.endDragging();
});
},
child: new GestureDetector(
onTap: () {
widget.callback(widget.caption, widget.index);
},
child: new Text(
widget.caption.caption,
style: new TextStyle(
color: widget.caption.color,
fontSize: widget.caption.fontSize,
),
),
),
feedback: new Material(
type: MaterialType.transparency,
child: new Text(
widget.caption.caption,
style: new TextStyle(
color: widget.caption.color,
fontSize: widget.caption.fontSize),
softWrap: true,
),
),
));
The Flexible does the trick
new Container(
child: Row(
children: <Widget>[
Flexible(
child: new Text("A looooooooooooooooooong text"))
],
));
This is the official doc https://flutter.dev/docs/development/ui/layout#lay-out-multiple-widgets-vertically-and-horizontally on how to arrange widgets.
Remember that Flexible and also Expanded, should only be used within a Column, Row or Flex, because of the Incorrect use of ParentDataWidget.
The solution is not the mere Flexible
In a project of mine I wrap Text instances around Containers. This particular code sample features two stacked Text objects.
Here's a code sample.
//80% of screen width
double c_width = MediaQuery.of(context).size.width*0.8;
return new Container (
padding: const EdgeInsets.all(16.0),
width: c_width,
child: new Column (
children: <Widget>[
new Text ("Long text 1 Long text 1 Long text 1 Long text 1 Long text 1 Long text 1 Long text 1 Long text 1 Long text 1 Long text 1 Long text 1 Long text 1 Long text 1 Long text 1 ", textAlign: TextAlign.left),
new Text ("Long Text 2, Long Text 2, Long Text 2, Long Text 2, Long Text 2, Long Text 2, Long Text 2, Long Text 2, Long Text 2, Long Text 2, Long Text 2", textAlign: TextAlign.left),
],
),
);
[edit] Added a width constraint to the container
Using Ellipsis
Text(
"This is a long text",
overflow: TextOverflow.ellipsis,
),
Using Fade
Text(
"This is a long text",
overflow: TextOverflow.fade,
maxLines: 1,
softWrap: false,
),
Using Clip
Text(
"This is a long text",
overflow: TextOverflow.clip,
maxLines: 1,
softWrap: false,
),
Note:
If you are using Text inside a Row, you can put above Text inside Expanded like:
Expanded(
child: AboveText(),
)
Use Expanded
Expanded(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Text(_name, style: Theme.of(context).textTheme.subhead),
new Container(
margin: const EdgeInsets.only(top: 5.0),
child: new Text(text),
),
],
),
If it's a single text widget that you want to wrap, you can either use Flexible or Expanded widgets.
Expanded(
child: Text('Some lengthy text for testing'),
)
or
Flexible(
child: Text('Some lengthy text for testing'),
)
For multiple widgets, you may choose Wrap widget. For further details checkout this
Try Wrap widget to wrap text as text grows:
Example:
Wrap(
direction: Axis.vertical, //Vertical || Horizontal
children: <Widget>[
Text(
'Your Text',
style: TextStyle(fontSize: 30),
),
Text(
'Your Text',
style: TextStyle(fontSize: 30),
),
],
),
You Can Wrap your widget with Flexible Widget and than you can set property of Text using overflow property of Text Widget.
you have to set TextOverflow.clip
for example:-
Flexible
(child: new Text("This is Dummy Long Text",
style: TextStyle(
fontFamily: "Roboto",
color: Colors.black,
fontSize: 10.0,
fontWeight: FontWeight.bold),
overflow: TextOverflow.clip,),)
hope this help someone :)
Container(
color: Color.fromRGBO(224, 251, 253, 1.0),
child: ListTile(
dense: true,
title: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
RichText(
textAlign: TextAlign.left,
softWrap: true,
text: TextSpan(children: <TextSpan>
[
TextSpan(text: "hello: ",
style: TextStyle(
color: Colors.black, fontWeight: FontWeight.bold)),
TextSpan(text: "I hope this helps",
style: TextStyle(color: Colors.black)),
]
),
),
],
),
),
),
You can use Flexible, in this case the person.name could be a long name (Labels and BlankSpace are custom classes that return widgets) :
new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Flexible(
child: Labels.getTitle_2(person.name,
color: StyleColors.COLOR_BLACK)),
BlankSpace.column(3),
Labels.getTitle_1(person.likes())
]),
BlankSpace.row(3),
Labels.getTitle_2(person.shortDescription),
],
)
I am developing a screen where I have to show suggestions list below the textfield.
I want to achieve this
I have developed this so far
Following code shows textfield with suggestions in a list.
#override
Widget build(BuildContext context) {
final header = new Container(
height: 39.0,
padding: const EdgeInsets.only(left: 16.0, right: 2.0),
decoration: _textFieldBorderDecoration,
child: new Row(
children: <Widget>[
new Expanded(
child: new TextField(
maxLines: 1,
controller: _controller,
style: _textFieldTextStyle,
decoration:
const InputDecoration.collapsed(hintText: 'Enter location'),
onChanged: (v) {
_onTextChanged.add(v);
if (widget.onStartTyping != null) {
widget.onStartTyping();
}
},
),
),
new Container(
height: 32.0,
width: 32.0,
child: new InkWell(
child: new Icon(
Icons.clear,
size: 20.0,
color: const Color(0xFF7C7C7C),
),
borderRadius: new BorderRadius.circular(35.0),
onTap: (){
setState(() {
_controller.clear();
_places = [];
if (widget.onClearPressed != null) {
widget.onClearPressed();
}
});
},
),
),
],
),
);
if (_places.length > 0) {
final body = new Material(
elevation: 8.0,
child: new SingleChildScrollView(
child: new ListBody(
children: _places.map((p) {
return new InkWell(
child: new Container(
height: 38.0,
padding: const EdgeInsets.only(left: 16.0, right: 16.0),
alignment: Alignment.centerLeft,
decoration: _suggestionBorderDecoration,
child: new Text(
p.formattedAddress,
overflow: TextOverflow.ellipsis,
maxLines: 1,
style: _suggestionTextStyle,
),
),
onTap: () {
_getPlaceDetail(p);
},
);
}).toList(growable: false),
),
),
);
return new Container(
child: new Column(
children: <Widget>[header, body],
),
);
} else {
return new Container(
child: new Column(
children: <Widget>[header],
),
);
}
}
Header(Textfield) and body(Suggestions List - SingleChildScrollView with ListBody) is wrapped inside the Column widget, and column expands based on the total height of the children.
Now the problem is as Column expands, layout system pushes other widgets on screen to the bottom. But I want other widgets to stay on their positions but suggestion list starts to appear on top of other widgets.
How can I show suggestions list on top of other widgets? And the suggestions list is dynamic, as user types I call the Google Places API and update the suggestions list.
I have seen there is showMenu<T>() method with RelativeRect positions but it doesn't fulfills my purpose, my suggestion list is dynamic(changing based on user input) and the styling for each item I have is different from what PopupMenuItem provides.
There is one possibility I can think of using Stack widget as root widget of this screen and arrange everything by absolute position and I put suggestion list as a last child of the stack children list. But it is not the right solution I believe.
What other possibilities I need to look into? What other Widgets can be used here in this use-case?
And again use-case is simple, overlaying suggestion list on other widgets on the screen and when user tap any of the item from the list then hiding this overlaid suggestion list.
The reason why your autocomplete list pushes down the widgets below it is because the List is being expanded on the Container. You can use Flutter's Autocomplete widget and it should inflate the autocomplete list over other widgets.
var fruits = ['Apple', 'Banana', 'Mango', 'Orange'];
_autoCompleteTextField() {
return Autocomplete(
optionsBuilder: (TextEditingValue textEditingValue) {
if (textEditingValue.text == '') {
return const Iterable<String>.empty();
}
return fruits.where((String option) {
return option
.toLowerCase()
.contains(textEditingValue.text.toLowerCase());
});
},
onSelected: (String selection) {
debugPrint('You just selected $selection');
},
);
}
In Android we can position elements in a linear layout using LayoutGravity , I would like to know how to achieve the same in Flutter. I have widgets in a column and I would like some widgets to be position on the left, some on the right and some on the left. How can I achieve this? Here is my code:
return new Container(
margin: const EdgeInsets.only(top: 16.0),
color: Colors.white,
child: new Column(
children: <Widget>[
//the following textfields must be positioned on the right, but they are on the center
new Text("Hair cut",),
new Text("Shampoo",),
//the button is in the center and that is correct
new RaisedButton(
onPressed: ()=>{},
color: Colors.purple,
child: new Text("Book",style: new TextStyle(color: Colors.white),),
)
],
),
);
Setting crossAxisAlignment to CrossAxisAlignment.end moves everything to the right. I tried adding the textfields in their own Column widget and setting crossAxisAlignment to end but nothing happens.
You can set crossAxisAlignment for a generic alignment. And then override it for a specific item by wrapping it in Align widget.
new Column(
children: <Widget>[
//the following textfields must be positioned on the right, but they are not the center
new Align(
alignment: Alignment.centerRight,
child: new Text("Hair cut"),
),
new Align(
alignment: Alignment.centerRight,
child: new Text("Shampoo"),
),
//the button is in the center and that is correct
new RaisedButton(
onPressed: () => {},
color: Colors.purple,
child: new Text(
"Book",
style: new TextStyle(color: Colors.white),
),
)
],
),
You may also want to wrap your Column into a IntrinsicWidth if you don't want your column to fill the width.
I'm learning Flutter, and I've made some VERY simple modifications to the starter app, so that the floating button changes the text item to a random string from an array.
The problem is that the text is too close to the edge of the screen--needs padding. But whenever I try to add a padding: element in any number of places, VSCode doesn't seem to like it. I've seen padding used in other example code, but can't seem to get it to work in this case.
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(
'Welcome to DadBot!',
),
new Text(
_txt,
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: new FloatingActionButton(
onPressed: _changeText,
tooltip: 'Increment',
child: new Icon(Icons.add),
),
);
}
The easiest way to get padding is to wrap your widget in a Padding widget and specify the offset you want.
Fixed the issue by wrapping the Text widget in question within a Padding class, like so:
new Padding(
padding: new EdgeInsets.all(10.0),
child: new Text(
_txt,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.display1,
),
),
I'm still getting used to the way Flutter does things, but I like it!