I am using a textformfield in my application. The cursor keeps moving to the left most side of the text. To solve this issue I added a listener:
final TextEditingController _controller = TextEditingController();
#override
Widget build(BuildContext context) {
_controller.text = widget.localLayoutItem.cx.toInt().toString();
_controller.addListener(() {
_controller.value = _controller.value.copyWith(
text: _controller.text,
selection: TextSelection.fromPosition(TextPosition(
offset: _controller.text.length,
)),
composing: TextRange.empty,
);
});
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextFormField(
controller: _controller,
decoration: const InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.only(left: 10),
iconColor: Colors.grey,
),
onChanged: (value) {
FocusedItemModel.of(context).redraw();
widget.localLayoutItem.cx = double.parse(value);
},
),
],
);
}
The textfield value is directly connected to the widgets x-axis value so if the widget moves I need to update the textfield value as well and vice-versa.
Problem:
After adding the listener the cursor is staying on the right most but I lost functionality like using the arrow key to a desired character or deleting all characters.
how to solve this issue?
update the text editing controller like this
TextEditingController questionController = TextEditingController.fromValue(TextEditingValue(
text: somevalue,
selection: TextSelection( baseOffset: somevalue.length,
extentOffset: somevalue.length),
)
I want to create a StaggeredGridView and fill it with images that the user uploads. The problem is that the type of StaggeredGridView is String or ImageProvider<Object> and the file is PickedFile or File
What is the solution ??
class GalleryClassOneState extends State<GalleryClassOne> {
List<File> arrayImage = [];
File sampleImage;
final _picker = ImagePicker();
// #override
// void initState() {
// super.initState();
// DatabaseReference images =
// FirebaseDatabase.instance.reference().child("NeuralNetwork");
// }
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Galeria clase 1'),
),
body: Container(padding: EdgeInsets.all(8), child: galeria(arrayImage)),
floatingActionButton: FloatingActionButton(
onPressed: _optionsDialogBox,
tooltip: 'Pick Image',
child: Icon(Icons.add_outlined),
),
);
}
Widget galeria(List<File> arrayImage) {
return StaggeredGridView.countBuilder(
crossAxisCount: 4,
itemCount: 11,
itemBuilder: (BuildContext context, int index) {
return ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Container(
color: Colors.deepPurple,
child: Column(
children: <Widget>[
Image.network(arrayImage[index])
],
),
),
);
},
// staggeredTileBuilder: (int index) => new StaggeredTile.fit(1),
staggeredTileBuilder: (int index) =>
new StaggeredTile.count(2, index.isEven ? 2 : 1),
mainAxisSpacing: 10.0,
crossAxisSpacing: 10.0,
);
}
}
We will need to work with the images as bytes instead of files. First, make arrayImage a List<Uint8List>. Here we will store a list of the byte arrays representing an image loaded in memory. Update the galeria() method to accept a List<Uint8List> as well.
Now in the optionsDialogBox() method, we will use the results of the _picker like so:
_picker.getImage(source: ImageSource.gallery).then((pickedFile) {
// read the bytes from the PickedFile
pickedFile.readAsBytes().then((bytes) {
// add the image as bytes to the arrayImage list and update the UI
setState(() => arrayImage.add(bytes));
});
});
When we create our Image widget, we will use the Image.memory() constructor passing to it the bytes representing our image.
Image.memory(arrayImage[index])
I'm new at Flutter and I'm trying to build a simple google maps app. I've already implemented google maps to the app and it is running perfect.
But now I want to add google maps autocomplete and I can't find a simple tutorial or example that is focused on it.
I have a TextField and I want to show places and addresses below it according to what the user types.
After showing the results, I need to get its latitude and longitude to mark on the map. The code below represents my BottomSheet, that contains my TexField and need to implement some list below it after some written text.
void _settingModalBottomSheet(context) {
double statusBarHeight = MediaQuery.of(context).padding.top;
showModalBottomSheet(
context: context,
builder: (builder) {
return Container(
padding: EdgeInsets.only(top: statusBarHeight),
color: Colors.transparent,
child: Container(
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.only(
topLeft: const Radius.circular(10.0), topRight: const Radius.circular(10.0))),
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 8.0, left: 8.0, right: 8.0),
child: Container(
height: 50.0,
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: Colors.white
),
child: TextField(
textInputAction: TextInputAction.search,
decoration: InputDecoration(
hintText: "Para onde vamos?",
border: InputBorder.none,
contentPadding: EdgeInsets.only(left: 15.0, top: 15.0),
suffixIcon: IconButton(
icon: Icon(Icons.search),
onPressed: searchAndNavigate,
iconSize: 30.0,
)
),
onChanged: (val) {
setState(() {
searchAddr = val;
}
);
},
onSubmitted: (term) {
searchAndNavigate();
},
),
),
),
],
)
),
);
}
);
}
You can use flutter_google_places plugin which shows the places in the autocomplete list as you type it and also returns lat and long of the place/address selected.
===== Working code =======
Add flutter_google_places plugin and import it in your dart file.
Add geo_coder plugin and import it in same dart file. (Required to access geocoding services)
Generate google api key for your project.
main.dart:
void main() => runApp(MyApp());
const kGoogleApiKey = "Api_key";
GoogleMapsPlaces _places = GoogleMapsPlaces(apiKey: kGoogleApiKey);
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: demo(),
),
);
}
}
class demo extends StatefulWidget {
#override
demoState createState() => new demoState();
}
class demoState extends State<demo> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
alignment: Alignment.center,
child: RaisedButton(
onPressed: () async {
// show input autocomplete with selected mode
// then get the Prediction selected
Prediction p = await PlacesAutocomplete.show(
context: context, apiKey: kGoogleApiKey);
displayPrediction(p);
},
child: Text('Find address'),
)
)
);
}
Future<Null> displayPrediction(Prediction p) async {
if (p != null) {
PlacesDetailsResponse detail =
await _places.getDetailsByPlaceId(p.placeId);
var placeId = p.placeId;
double lat = detail.result.geometry.location.lat;
double lng = detail.result.geometry.location.lng;
var address = await Geocoder.local.findAddressesFromQuery(p.description);
print(lat);
print(lng);
}
}
}
Result:
When you tap on Find Address button, it opens new screen with built-in search app bar in which you can type address / place you are looking for which shows corresponding results in autocomplete list and prints lat and long of the place you selected.
lat: 52.3679843
lng: 4.9035614
Using HTML I can add a bullet points to a paragraph like this:
<ul>
<li> example </li>
<li> example </li>
<li> example </li>
<ul>
How can I write bullet point form in Flutter?
new Text(''),
If you don't want to download another library (e.g. flutter_markdown), and one or more of your list items have lengthy text that spans several rows, I'd go with Raegtime's answer. However, since it assumes a string with line breaks, I want to make a version for a list with strings, which is a more common scenario. In the code below, Column makes the list items come on different rows, and Row makes the bullet points have empty space below themselves.
import 'package:flutter/material.dart';
class UnorderedList extends StatelessWidget {
UnorderedList(this.texts);
final List<String> texts;
#override
Widget build(BuildContext context) {
var widgetList = <Widget>[];
for (var text in texts) {
// Add list item
widgetList.add(UnorderedListItem(text));
// Add space between items
widgetList.add(SizedBox(height: 5.0));
}
return Column(children: widgetList);
}
}
class UnorderedListItem extends StatelessWidget {
UnorderedListItem(this.text);
final String text;
#override
Widget build(BuildContext context) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("• "),
Expanded(
child: Text(text),
),
],
);
}
}
We can use it as such:
UnorderedList([
"What conclusions can we draw from the implementation?",
"Are there any changes that need to be introduced permanently?"
])
And get the result:
Using markdown for this is overkill. Using • character is by far easier.
If you're too lazy to copy paste the character, here's a custom Text that does it for you:
class Bullet extends Text {
const Bullet(
String data, {
Key key,
TextStyle style,
TextAlign textAlign,
TextDirection textDirection,
Locale locale,
bool softWrap,
TextOverflow overflow,
double textScaleFactor,
int maxLines,
String semanticsLabel,
}) : super(
'• ${data}',
key: key,
style: style,
textAlign: textAlign,
textDirection: textDirection,
locale: locale,
softWrap: softWrap,
overflow: overflow,
textScaleFactor: textScaleFactor,
maxLines: maxLines,
semanticsLabel: semanticsLabel,
);
}
I tried using flutter_markdown and it seems to work. And of course you can change it to numbered/ordered or unordered list as you want.
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:flutter/material.dart';
void main() => runApp(Demo());
class Demo extends StatelessWidget {
final testData = ["Example1", "Example2", "Example3", "Example100"];
#override
Widget build(BuildContext context) {
final _markDownData = testData.map((x) => "- $x\n").reduce((x, y) => "$x$y");
return MaterialApp(
home: Scaffold(
body: Container(
margin: EdgeInsets.all(40.0),
child: Markdown(data: _markDownData)),
));
}
}
I would better use utf-code. For list I think more comfortably will be something like:
class DottedText extends Text {
const DottedText(String data, {
Key key,
TextStyle style,
TextAlign textAlign,
TextDirection textDirection,
Locale locale,
bool softWrap,
TextOverflow overflow,
double textScaleFactor,
int maxLines,
String semanticsLabel,
}) : super(
'\u2022 $data',
key: key,
style: style,
textAlign: textAlign,
textDirection: textDirection,
locale: locale,
softWrap: softWrap,
overflow: overflow,
textScaleFactor: textScaleFactor,
maxLines: maxLines,
semanticsLabel: semanticsLabel,);
}
#Snurrig - Excellent answer. Works great! Thanks a lot!
Modified it to create an ordered/numbered list, as well.
See below:
class OrderedList extends StatelessWidget {
OrderedList(this.texts);
final List<dynamic> texts;
#override
Widget build(BuildContext context) {
var widgetList = <Widget>[];
int counter = 0;
for (var text in texts) {
// Add list item
counter++;
widgetList.add(OrderedListItem(counter, text));
// Add space between items
widgetList.add(SizedBox(height: 5.0));
}
return Column(children: widgetList);
}
}
class OrderedListItem extends StatelessWidget {
OrderedListItem(this.counter, this.text);
final int counter;
final String text;
#override
Widget build(BuildContext context) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("$counter. "),
Expanded(
child: Text(text),
),
],
);
}
}
you can use like this:
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'\u2022',
style: TextStyle(
fontSize: 16,
height: 1.55,
),
),
SizedBox(
width: 5,
),
Expanded(
child: Container(
child: Text(
str,
textAlign: TextAlign.left,
softWrap: true,
style: TextStyle(
fontSize: 16,
color: Colors.black.withOpacity(0.6),
height: 1.55,
),
),
),
),
],
);
You can use LineSplitter, Row, Column, and the ASCII bullet point. All u need is a String with linebreaks.
String myStringWithLinebreaks = "Line 1\nLine 2\nLine 3";
Example in a ListTile
ListTile(
title: Text("Title Text"),
subtitle:
Column(
children: LineSplitter.split(myStringWithLinebreaks).map((o) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("• "),
Expanded(
child: Text(o),
)
],
);
}).toList())),
If you do not require markdowns everywhere, and just want to use them in one or two places, then adding a package or writing that much code for it is not a suitable idea.
You can copy the DOT from websites like emojipedia and paste it in front of your text.
here is an example:
Text("⚈ Provide, operate, and maintain our website"),
This will add bullet. Use it in a row with text.
Container(width: 10, height: 10, decoration:
BoxDecoration(shape: BoxShape.circle, color: Colors.black),),
Row(
children: [
_buildBullet(),
const SizedBox(width: 5),
_buildText(),
],
),
SizedBox _buildBullet() {
return SizedBox(
height: 7,
width: 7,
child: TextButton(
style: TextButton.styleFrom(
backgroundColor: Color(0xFFF8B407),
shape: const CircleBorder(),
),
child: const Text(''),
onPressed: () {},
),
);
}
Text _buildText() {
return const Text(
'Lorem Ipsum is simply dummy text of the printing and typesetting',
style: TextStyle(fontSize: 24, color: Colors.white),
);
}
I have a list of Chips, and I want them to change color when user click on them.
For instance if I click on the first Chip its color become black, and every other chips are grey. Then if I click on the second Chip its color become black and first Chip color become grey and so on.
I can't find a beautiful/simple way to do this, have you any ideas ?
Thanks a lot
Here is how you can do it:
Widget _myChip(int number, String name) {
return new Padding(
padding: const EdgeInsets.all(8.0),
child: new InkWell(
child: new Chip(
label: new Text(name,
style: new TextStyle(
color: selectedChip == number ? Colors.white : Colors.black
),),
backgroundColor:
selectedChip == number ? Colors.black : Colors.grey),
onTap: () {
setState(() {
selectedChip = number;
});
},
),
);
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Stackoverflow'),
),
body: new Column(
children: <Widget>[
_myChip(1, 'Arnold'),
_myChip(2, 'Sylvester'),
_myChip(3, 'Priscilla'),
_myChip(4, 'Parge'),
_myChip(5, 'Something'),
],
),
);
}
You need to give chips a unique number to identify and use inline if to change the color of the chips.