children centered in a row - widget

Im using Align Widget to center children in a Row but It is not working...what I doing wrong?
This is the code:
....
home.dart
....
#override
Widget build(BuildContext context){
_context = context;
return new Scaffold(
appBar: new AppBar(title: Text("MiniCon")),
body: new Container(child: new Column(children:[
new Align(alignment:Alignment.center,child:new Row(children:[
_commons.makeEditText("Ahorro Real", grey, false),
_commons.makeEditText("Ahorro Actual", black, true),
_commons.makeEditText("Gastos", black, true)
])),
new Row(children:[
_commons.makeEditText("Ahorro Real", grey, false)
])
])));
}
....
_commons.dart
....
Widget makeEditText(String label, Color labelColor, bool enabled) {
return
new Padding(padding:EdgeInsets.all(2.5), child:
new Container(decoration:
new BoxDecoration(border:
new Border.all(width:2.0)),padding: new
new EdgeInsets.all(10.0),width:110.0,child:
new TextField(enabled: enabled,
style: TextStyle(color: labelColor),
decoration: new InputDecoration(
labelStyle: TextStyle(fontSize: 15.0), labelText: label),
)));
}
Thanks in advance!!

This Centers the Row:
body: Container(
child: Column(children: [
Row(mainAxisAlignment: MainAxisAlignment.center, children: [
makeEditText("Ahorro Real", Colors.grey, false),
makeEditText("Ahorro Actual", Colors.black, true),
makeEditText("Gastos", Colors.green, true)
]),
new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [makeEditText("Ahorro Real", Colors.red, false)])
]),
),

Use the mainAxisAlignment / crossAxisAlignment property of the Column/Row widgets instead.

Related

Flutter how to in a expanded list view

Hello good day everyone i want to make my listview into a expanded listview i pull my data using mysql
i want to display first the transaction id and the vesselname then in the side it has it mut have a arrow that when you click it it will show other information details.
Widget build(BuildContext context) {
return Scaffold(
body: RefreshIndicator(
onRefresh: getData,
key: _refresh,
child: loading
? Center(child: CircularProgressIndicator())
: ListView.builder(
itemCount: list.length,
itemBuilder: (context, i) {
final x = list[i];
debugPrint(x.toString());
return Container(
padding: EdgeInsets.all(20.0),
child: Row(
children: <Widget>[
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
the data will be shown first is transaction id and vessel name a arrow icon on the side when it is click it will show the other information
Text(
'Transaction ID:\t' + x.transaction_id,
style: TextStyle(
fontSize: 20.0, fontWeight: FontWeight.bold),
),
Text('Vessel Name:\t' + x.vesselname,
style: TextStyle(fontSize: 20.0)),
//this will be the the information displayed after the side arrow will be click
Text('Type of Port :\t' + x.typeofport.capitalize(),
style: TextStyle(fontSize: 20.0)),
Text('Vessel Number:\t' + x.voyageno,
style: TextStyle(fontSize: 20.0)),
Text('Ship Call #:\t' + x.scn,
style: TextStyle(fontSize: 20.0)),
Text('OR #:\t' + x.ornum,
style: TextStyle(fontSize: 20.0)),
Text(
'Amount:\t ' +
money.format(int.parse(x.payment)),
style: TextStyle(fontSize: 20.0)),
Text('Status:\t' + x.status.toUpperCase(),
style: TextStyle(
fontSize: 25.0,
fontWeight: FontWeight.bold,
color: x.status == 'pending'
? Colors.red
: Colors.green)),
Divider()
],
),
),
],
),
);
},
),
));
}
}
first when you fetch data in your DTO you can put bool variable inside or you can remap your DTO and put variable bool
so your variable inside somehow like this:
Map<DTO, bool>
or
DTO{
........, bool collapsed;
}
then in your code when you create your builder
final x = list[i]; >> changed to entries if you used Map [final x = mapData[i].entries.toList()]
return Container(
padding: EdgeInsets.all(20.0),
child: GestureDetector(
onTap: (){
setState({
// if you using Map
x[i] = !x.value;
// if you using DTO
x.collapsed = !x.collapsed;
});
},
child: Column(
children:[
// Your Header
Row(
children: <Widget>[
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
the data will be shown first is transaction id and vessel name a arrow icon on the side when it is click it will show the other information
Text(
'Transaction ID:\t' + x.transaction_id,
style: TextStyle(
fontSize: 20.0, fontWeight: FontWeight.bold),
),
Text('Vessel Name:\t' + x.vesselname,
style: TextStyle(fontSize: 20.0)),
]
// Your Detail
// [if you used DTO]
if(!x.collapsed) Container(child:.......)
// [if you used Map]
if(!x.value) Container(child:......)
)
)
this is only the logic of changing the list inside to become Collapsible listView
explore ExpansionTile in flutter, I think it fits your requirement.

GoogleMap's onCameraIdle stops firing when in a SingleChildScrollView

I have a design where a SingleChildScrollView has a GoogleMap on the first 50% on the screen, and a listing of items in the lower 50%. The user can scroll the entire view up to look at all of the listings. However, at times the Map stops firing the onCameraIdle if the users scrolls the page, and it just won't start firing it again.
onCameraMove and onTap works just fine. It is just onCameraIdle that won't fire.
SingleChildScrollView(
child: Column(
children: <Widget>[
Stack(
children: <Widget>[
Container(
height: screenSize.height / 2,
child: GoogleMap(
key: Key("GMap"),
mapType: MapType.normal,
markers: Set<Marker>.of(markers.values),
gestureRecognizers: Set()
..add(Factory<PanGestureRecognizer>(
() => PanGestureRecognizer()))
..add(
Factory<VerticalDragGestureRecognizer>(
() => VerticalDragGestureRecognizer()),
)
..add(
Factory<HorizontalDragGestureRecognizer>(
() => HorizontalDragGestureRecognizer()),
)
..add(
Factory<ScaleGestureRecognizer>(
() => ScaleGestureRecognizer()),
),
initialCameraPosition: CameraPosition(
target: LatLng(14.551620, 121.053329), zoom: 14.5),
onMapCreated: (GoogleMapController controller) {
if (!_controller.isCompleted) {
_controller.complete(controller);
_lastCameraPosition = CameraPosition(
target: LatLng(14.551620, 121.053329), zoom: 14.5);
}
},
myLocationEnabled: true,
myLocationButtonEnabled: true,
onCameraIdle: () {
print("547: onCameraIdle");
_fetchOffers();
},
onCameraMove: (value) {
print("552: onCameraMove");
_lastCameraPosition = value;
},
onTap: (value) {
// Load items for current view if deselecting a marker
print('556: Tapped outside');
},
),
),
Positioned(
top: 50,
right: 20,
child: Container(
height: 30,
decoration: BoxDecoration(
border: Border.all(
color: _userBalance > 0
? globals.themeColor4
: globals.themeColor2,
width: 2),
boxShadow: [
BoxShadow(
blurRadius: 10.0,
color: Colors.black.withOpacity(.5),
offset: Offset(3.0, 4.0),
),
],
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(10.0))),
child: Center(
child: Padding(
padding: EdgeInsets.fromLTRB(10, 5, 10, 5),
child: Text(
"Balance: \u{20B1} ${_userBalance.toStringAsFixed(0)}",
style: TextStyle(
color: Colors.black,
fontSize: 14,
),
),
),
),
),
),
],
),
AnimatedContainer(
color: Colors.white,
// Use the properties stored in the State class.
width: double.infinity,
height: _loaderHeight,
// Define how long the animation should take.
duration: Duration(seconds: 1),
// Provide an optional curve to make the animation feel smoother.
curve: Curves.fastOutSlowIn,
child: Center(
child: Text(
"Loading, please wait",
style: TextStyle(color: Colors.grey),
),
),
),
Container(
color: Colors.white,
child: _offers == null
? Container(
child: Padding(
padding: EdgeInsets.all(30),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Icon(MdiIcons.foodAppleOutline,
size: 60, color: globals.themeColor4),
Padding(padding: EdgeInsets.only(right: 20)),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("Fetching offers",
style: TextStyle(
color: globals.themeColor4,
fontWeight: FontWeight.bold)),
Padding(padding: EdgeInsets.only(top: 5)),
Text(
"We are fetching offers for you, please hold on...",
style: TextStyle(color: Colors.grey)),
],
),
),
],
),
),
)
: Column(children: _offers),
),
],
),
),
Has anyone encountered this before and have a solution to it?
I replicated a simple version of your sample, but I wasn’t able to reproduce an issue with onCameraIdle not firing.
Now, based off of my sample, there were some behaviors that you could have misinterpreted as not working, but is actually the scrollview’s behavior taking over (since this is all inside a scrollview):
Sometimes a downward gesture on the map would pull on the scrollview instead of the map.
And an upward gesture would scroll the scrollview instead of interacting with the map.
But without any further details into the rest of your code, or a mcve that can easily reproduce your issue, it’s hard to say what’s really going on.
However, as Patrick Kelly mentioned, it’s also possible that the lack of a KeepAlive might have eventually led to the temporary disposing of your maps widget. Which is why ListView was suggested because this feature is built into it.
On the other hand, you can also implement AutomaticKeepAliveClientMixin for a similar effect, as seen over at https://stackoverflow.com/a/51738269/6668797 (but beware of the warning for the widget disposing).
Anyways, here’s my sample, and I had to make an educated guess on what your _fetchOffers() is:
class _MyHomePageState extends State<MyHomePage> {
// testing
int fetchCount = 0;
List<Widget> _offers;
_fetchOffers() {
fetchCount++;
// simulate varying data
var rng = new Random();
int start = rng.nextInt(10);
int end = start + 3 + rng.nextInt(30);
// build sample list
List<Widget> list = new List();
for (int i = start; i < end; i++) {
list.add(Text('offer$i', style: new TextStyle(fontSize: 30.0)));
}
// assuming you are using setState()
setState(() {
_offers = list;
});
}
// from google maps sample
Completer<GoogleMapController> _controller = Completer();
static final CameraPosition _kGooglePlex = CameraPosition(
target: LatLng(37.42796133580664, -122.085749655962),
zoom: 14.4746,
);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(widget.title)),
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Stack(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height / 2,
child: GoogleMap(
mapType: MapType.normal,
initialCameraPosition: _kGooglePlex,
gestureRecognizers: Set()
..add(Factory<PanGestureRecognizer>(() => PanGestureRecognizer()))
..add(Factory<VerticalDragGestureRecognizer>(() => VerticalDragGestureRecognizer()))
..add(Factory<HorizontalDragGestureRecognizer>(() => HorizontalDragGestureRecognizer()))
..add(Factory<ScaleGestureRecognizer>(() => ScaleGestureRecognizer())),
onMapCreated: (GoogleMapController controller) {
_controller.complete(controller);
},
onCameraIdle: () {
_fetchOffers();
},
),
),
]
),
Container(
child: _offers == null
? Container(child: Text("Fetching offers"))
: Column(children: _offers)
),
],
),
),
floatingActionButton: FloatingActionButton(
// for logging _fetchOffers activity
child: Text(fetchCount.toString())
),
);
}
}
onCameraIdle fired every time for me, and I could visually confirm it with the changing offers data as well as the fetchCount log.
You could use a ListView or a CustomScrollView with KeepAlive
This prevents Widgets from being thrown out when scrolled out of view.
I would alternatively recommend digging into the ScrollController class

How to hook up data from local json to achieve search with autocomplete text in list?

I am trying to implement input search feature wherein typing a search text will display suggested text and user can select relevant text from list and hit search button to proceed to corresponding screen. The suggested text is in local json and I added it under under assets/ folder and in pubspec.yaml.
The search textfield is:
The code for above is:
new TextField(
style: new TextStyle(
color: Colors.white,
fontSize: 16.0),
cursorColor: Colors.green,
decoration: new InputDecoration(
suffixIcon: Container(
width: 85.0,
height: 60.0,
color: Colors.green,
child: new IconButton(
icon: new Image.asset('assets/search_icon_ivory.png',color: Colors.white, height: 18.0,),
onPressed: () {
},
),
),
fillColor: Colors.black,
contentPadding: new EdgeInsets.fromLTRB(10.0, 30.0, 10.0, 20.0),
filled: true,
hintText: 'What Do You Need Help With?',
hintStyle: new TextStyle(
color: Colors.white
)
)
)
The local json data sample is:
I want to achieve above using autocomplete_textfield package which I've installed and imported and referring this example.
I would like to know how to get started with this and integrate parsing from local json, hook that data using autocomplete_textfield package to achieve my goal. I haven't done parsing json in flutter yet so looking for guidance on how to do that.
The end result I am looking for is like this:
***************** Edit **************
I am now able to parse data from local json and display it in a listView using a demo app. For it, I created a new model class `services.dart' as below:
class Categories {
String serviceCategory;
String servCategoryDesc;
int id;
String autocompleteterm;
String category;
String desc;
Categories({
this.serviceCategory,
this.servCategoryDesc,
this.id,
this.autocompleteterm,
this.category,
this.desc
});
factory Categories.fromJson(Map<String, dynamic> parsedJson) {
return Categories(
serviceCategory:parsedJson['serviceCategory'] as String,
servCategoryDesc: parsedJson['serviceCategoryDesc'] as String,
id: parsedJson['serviceCategoryId'],
autocompleteterm: parsedJson['autocompleteTerm'] as String,
category: parsedJson['category'] as String,
desc: parsedJson['description'] as String
);
}
}
Used builder function to retrieve and display value in listview as below:
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Load local JSON file"),
),
body: new Container(
child: new Center(
// Use future builder and DefaultAssetBundle to load the local JSON file
child: new FutureBuilder(
future: DefaultAssetBundle
.of(context)
.loadString('assets/services.json'),
builder: (context, snapshot) {
// Decode the JSON
Map data = json.decode(snapshot.data
.toString());
print(data);
final List<Categories> items = (data['data'] as List).map((i) => new Categories.fromJson(i)).toList();
for (final item in items) {
print(item.category);
return new ListView.builder(
itemBuilder: (BuildContext context, int index) {
return new Card(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
new Text('Service Category: ' + items[index].category),
new Text('Category' + items[index].categoryDesc),
new Text('Auto complete term' + items[index].autocompleteterm),
new Text('Desc' + items[index].desc)
],
),
);
},
);
}
}
)
)
)
);
}
}
In my target app, added required code that uses autocomplete_textfield package that shows a static list of suggestions as of now :
#override
Widget build(BuildContext context) {
textField = new AutoCompleteTextField<String>
(style: new TextStyle(
color: Colors.white,
fontSize: 16.0),
decoration: new InputDecoration(
suffixIcon: Container(
width: 85.0,
height: 60.0,
color: Colors.green,
child: new IconButton(
icon: new Image.asset('assets/search_icon_ivory.png',color: Colors.white,
height: 18.0,),
onPressed: (){},
),
),
fillColor: Colors.black,
contentPadding: new EdgeInsets.fromLTRB(10.0, 30.0, 10.0, 20.0),
filled: true,
hintText: 'What Do You Need Help With ?',
hintStyle: new TextStyle(
color: Colors.white
)
),
submitOnSuggestionTap: true,
clearOnSubmit: true,
textChanged: (item){
currentText = item;
},
textSubmitted: (item) {
setState(() {
currentText = item;
});
},
key: key,
suggestions: suggestions,
itemBuilder: (context, item) {
return new Padding(
padding: EdgeInsets.all(8.0), child: new Text(item));
},
itemSorter: (a, b) {
return a.compareTo(b);
},
itemFilter: (item, query) {
return item.toLowerCase().startsWith(query.toLowerCase());
});
Column body = new Column(children: [
new GestureDetector(
child: new ListTile(
title: textField,
onTap: () {
setState(() {
if (currentText != "") {
added.add(currentText);
textField.clear();
currentText = "";
}
});
}
)
)
]
);
body.children.addAll(added.map((item) {
return new ListTile(
title: new Text(item)
);
}));
return Scaffold(
resizeToAvoidBottomPadding: false,
backgroundColor: Color(0xFF13212C),
appBar: AppBar(
title: Text(''),
),
drawer: appDrawer(),
body: new Center(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
new Column(
children: <Widget>[
textField
Above code shows in UI as below:
I now would like to know how to hook the builder function retrieving json data in my target app, so that instead of static list of strings, the dropdown would show suggestions from json (as posted in my original question's screenshot).
If you found doing this manually it too much, this is actually a flutter package that does this. There are two examples on the package site too.
Do be warned, this is currently a bug in the package (I have raised a PR to fix it but the package owner has been too busy to review any PR recently). Depending on how you use it, the bug may not affect you.

many json loading in the same screen, how to await one and continue?

I have a screen with multiples json request, but it is loading all in the same time, i want to when finish one start the another until the end.
new CustomScrollView(
cacheExtent: height * 5,
slivers: [
new SliverList(
delegate: new SliverChildListDelegate(
[
new RelatorioVendPeriodoAPeriodo(),
new RelatorioDiasDaSemanas(),
new RelatorioVendasTotalidasPorPeriodo(),
new RelatorioDasVendasTotsProdutos(),
new RelatorioMensals(),
]
)
)
]
),
this classes loads a json request, how to divide and await one to start other?
Here one of this classes return method:
Widget build(BuildContext context) {
double height = (MediaQuery.of(context).size.height) - kRadialReactionRadius - kToolbarHeight;
return new Container(
height: height,
padding: new EdgeInsets.only(left: 5.0, right: 5.0),
child: new Card(
elevation: 10.0,
child:
new Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Column(crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new ListTile(
trailing:
_buildCounterButton(),
title: new Center(child: new Text('FATURAMENTO MENSAL', style: new TextStyle(fontWeight: FontWeight.bold))),
subtitle: new Icon(Icons.info),
onTap: _showDialog,
),
new FutureBuilder<List<RelatorioMensal>>(
future: fetchRelatorioMensal(new http.Client(), "", '$dateFinal1Sem'),
builder: (context, snapshot) {
if (snapshot.hasError) print(snapshot.error);
return snapshot.hasData
? new porVendaMensal(listVendasMensais: snapshot.data,)
: new Center(child: new CircularProgressIndicator());
}
),
],),]
),
),
);
}

Flutter exception caught by widgets library failed assertion

I am getting below exception. I am just learning Flutter.
Below is my code:
import 'package:flutter/material.dart';
void main() => runApp(new FriendlyChatApp());
const String _name = "Hammad Tariq";
class FriendlyChatApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: "Friendly Chat",
home: new ChatScreen(),
);
}
}
class ChatScreen extends StatelessWidget {
ChatScreen({this.text});
final String text;
#override
Widget build(BuildContext context) {
return new Container(
margin: const EdgeInsets.symmetric(vertical: 10.0),
child: new Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new Container(
margin: const EdgeInsets.only(right: 10.0),
child: new CircleAvatar(
child: new Text(_name),
),
),
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),
),
],
)
],
),
);
/*return new Scaffold(
appBar: AppBar(
title: new Text("Chat App"),
),
);*/
}
}
The issue is in the line
child: new Text(text)
where String text is null.
You've defined text as an optional parameter and you are not passing it from FriendlyChatApp.
If you require some inputs from parent page for the child to work properly then you can define it with #required annotation because you won't miss it accidentally.