Flutter textformfield cursor moving to front of the text - flutter-web

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),
)

Related

flutter listview with radio not showing in alertDialog

This is the code.
code:
class ThemeChangerWidget extends StatelessWidget {
final List<String> string = ['Light', 'Dark', 'Amoled'];
#override
Widget build(BuildContext context) {
final stateData = Provider.of<ThemeNotifier>(context);
final ThemeData state = stateData.getTheme();
return Theme(
data: state.copyWith(unselectedWidgetColor: state.accentColor),
child: AlertDialog(
backgroundColor: state.primaryColor,
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),
title: Text('Select Theme', style: state.textTheme.body1),
content: ListView.builder(
shrinkWrap: true,
itemBuilder: (context, index) {
return RadioListTile(
value: index,
groupValue: themes.indexOf(state),
onChanged: (ind) {
onThemeChanged(ind, stateData);
},
title: Text(
string[index],
style: state.textTheme.body2,
),
);
},
itemCount: string.length,
)),
);
}
}'
errors-The following assertion was thrown during performLayout():
RenderShrinkWrappingViewport does not support returning intrinsic dimensions.
some times throw this error instead of above LayoutBuilder does not support returning intrinsic dimensions.
Calculating the intrinsic dimensions would require instantiating every child of the viewport, which defeats the point of viewports being lazy.
If you are merely trying to shrink-wrap the viewport in the main axis direction, you should be able to achieve that effect by just giving the viewport loose constraints, without needing to measure its intrinsic dimensions.
AlertDialog uses an IntrinsicWidth widget that doesn't allow ListView.builder. You have to give a specific width to your ListView Example:
return AlertDialog(
title: Text('Dialog'),
content: SizedBox(
width: double.maxFinite,
child: ListView(
children: <Widget>[
//Your content here
],
),
),
);

More space between LabelText and HintText in TextFormField (Flutter)

I want to increase the distance between labelText and hintText in a TextFormField, and contentPadding: EdgeInsets.fromLTRB(x, x, x, x), doesn't help me at all, it does apply a padding but those elements remain together.
My preview:
You can do this with hintStyle and LabelStyle, set height attribute to what you want
You can see my test result in picture
code snippet
TextFormField(
decoration: const InputDecoration(
icon: Icon(Icons.person),
hintText: 'What do people call you?',
hintStyle: TextStyle(height:7, fontWeight: FontWeight.bold),
labelText: 'Name *',
labelStyle: TextStyle(height:5, fontWeight: FontWeight.bold),
),
full code
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
// This call to setState tells the Flutter framework that something has
// changed in this State, which causes it to rerun the build method below
// so that the display can reflect the updated values. If we changed
// _counter without calling setState(), then the build method would not be
// called again, and so nothing would appear to happen.
_counter++;
});
}
#override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
),
body: Center(
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child: Column(
// Column is also layout widget. It takes a list of children and
// arranges them vertically. By default, it sizes itself to fit its
// children horizontally, and tries to be as tall as its parent.
//
// Invoke "debug painting" (press "p" in the console, choose the
// "Toggle Debug Paint" action from the Flutter Inspector in Android
// Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
// to see the wireframe for each widget.
//
// Column has various properties to control how it sizes itself and
// how it positions its children. Here we use mainAxisAlignment to
// center the children vertically; the main axis here is the vertical
// axis because Columns are vertical (the cross axis would be
// horizontal).
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextFormField(
decoration: const InputDecoration(
icon: Icon(Icons.person),
hintText: 'What do people call you?',
hintStyle: TextStyle(height:7, fontWeight: FontWeight.bold),
labelText: 'Name *',
labelStyle: TextStyle(height:5, fontWeight: FontWeight.bold),
),
onSaved: (String value) {
// This optional block of code can be used to run
// code when the user saves the form.
},
validator: (String value) {
return value.contains('#') ? 'Do not use the # char.' : null;
},
),
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
Provided you are using a OutlineInputBorder, you can use textAlignVertical: TextAlignVertical.bottom, together with
decoration: InputDecoration(
contentPadding: EdgeInsets.only(top: 28),
border: OutlineInputBorder(
)
)
Adjust the contentPadding to your desired height.
I needed a TextField just with a label and no hint. My workaround to create space between was to provide the hint as an empty string. Hope this helps took me like 20 minutes to figure out 🙄
TextField(
decoration: InputDecoration(
hintStyle: TextStyle(
height: 3.0, // sets the distance between label and input
),
hintText: '', // needed to create space between label and input
labelStyle: TextStyle(
color: kWhiteTextColor,
fontSize: 20.0,
),
labelText: 'My first name is',
),
),
TextFormField(
controller: controller.fullNameController,
focusNode: controller.fullNameFocusNode,
enabled: false,
decoration: InputDecoration(
alignLabelWithHint: true,
labelText: fullNameLabel,
hintText: fullNameLabel,
labelStyle: TextStyle(
fontSize: 18,
height: 0.5, // Tweak this 1,2 moves label bottom-> -1,-2 moves label upwards
fontWeight: FontWeight.w500,
),
floatingLabelBehavior: FloatingLabelBehavior.always),
),
Figured it out!
Don't use labelText Parameter, instead, use the label parameter, wrap your text widget with padding widget then specify the amount of padding you want between label and text form field.
Like so
label: Padding( padding: Const EdgeInsets.all(10), child:Text('your label text')

How to create a simple google maps address search with autocomplete in flutter and get latitude and longitude?

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

How can I write a paragraph with bullet points using Flutter?

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),
);
}

OnPressed Set activeColor to a button of a list, and set inactiveColor to others btns - Flutter

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.

Resources