I am having difficulty to align components(widgets, html components, react components etc.) - css

I am new to flutter. However, I am having difficulty to align the widgets. I have also tried to learn CSS in the past. The thoughest part of it was to align the html components.
There are many properties like padding, margin, alignment, crossAxisalignment etc. Actually, I know where to use that properties, but when I use them the result is not what I expected.
However, I think if I can learn how to align in flutter. It will be easier to position in all others. For instance, I need to learn how to locate the color palette in the right and bottom of the phone. Every time when I need to locate something like that I am searching it and find the solution. That takes a lot of my time. So, what is the best way to learn how to position that widgets. Is there any source that I can use?
Here is the code:
import 'package:flutter/material.dart';
class Todo extends StatefulWidget {
#override
_TodoState createState() => _TodoState();
}
class _TodoState extends State<Todo> {
TextEditingController _controller = new TextEditingController();
List colors = [ Colors.grey[800], Colors.deepPurpleAccent, Colors.teal,Colors.amber];
int index=0;
String _text;
int _maxLength = 30;
#override
Widget build(BuildContext context) {
final bottom = MediaQuery.of(context).viewInsets.bottom;
return Scaffold(
backgroundColor:colors[index] ,
resizeToAvoidBottomInset: false,
resizeToAvoidBottomPadding: false,
body: SingleChildScrollView(
reverse: true,
child: Container(
padding: EdgeInsets.fromLTRB(0, 50, 0, bottom),
child: Stack(
children: [
TextField(
style: TextStyle(color: Colors.white),
maxLengthEnforced: true,
maxLength: _maxLength,
onTap: null,
controller: _controller,
autocorrect: false,
textCapitalization: TextCapitalization.sentences,
onChanged: (String text) {
if (text.length <= _maxLength)
_text = text;
else
_controller.text = text;
},
decoration: InputDecoration(
focusColor: Colors.red,
border: OutlineInputBorder(),
fillColor: Colors.white,
),
),
TextField(
style: TextStyle(color: Colors.white),
maxLines: null,
decoration: InputDecoration(
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
),
),
Positioned(
right: 5,
bottom: 0,
child: IconButton(
icon: Image.asset('assets/colorize.png'),
tooltip: 'Closes app',
onPressed: (){
setState(() {
if(index<colors.length)
index++;
if(index==colors.length)
index=0;
print("index: " + index.toString() + " len: " +colors.length.toString());
});
},
),
)
],
),
),
),
);
}
}

You can use a positioned widget, that will give you a freedom to position objects inside a STACK, but if you want your positioning to be more accurate / cleaner (still achievable with positioned widget), you can go with the Row and Column widgets,
Kindly refer to the flutter docs For Row Widget
they have some interactive examples to experiment with, for your need, what I would do is to use the "MediaQuery.of(context).size.height, and MediaQuery.of(context).size.width and reduce the icon size, or you can do this also,
This will position your palette in the right bottom of your screen and still have options to add other widgets to your app,
Stack(
children: [
Positioned(
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [Text("Hello")],
)
],
))
],
);
you will find the "Hello" in the right bottom of your screen for the code above.
Replace the Text widget with a choice of your own, and Happy Coding :)

I found the answe. Just need to use floatingActionButton outside the SingleChildScrollView. Thus, The color palette will stick into bottom-wight.
Here is the code
floatingActionButton: IconButton(
icon: Image.asset('assets/colorize.png'),
tooltip: 'Closes app',
onPressed: () {
setState(() {
if (index < colors.length) index++;
if (index == colors.length) index = 0;
print("index: " +
index.toString() +
" len: " +
colors.length.toString());
});
},
),

Related

Displays the same cart-quantity and total price

I am having issue with the cart notification panel as it displays the product-quantity and price of the previous user and is not updated even after i add products from new user account.
This is the code for notification panel
Widget build(BuildContext context) {
final _cartProvider = Provider.of<CartProvider>(context);
_cartProvider.getCartTotal();
return Container(
height: 45,
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
color: AppColors.buttonnavigation,
borderRadius: BorderRadius.only(
topRight: Radius.circular(18), topLeft: Radius.circular(18))),
child: Padding(
padding: const EdgeInsets.only(left: 10, right: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Center(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text(
'${_cartProvider.cartQty}${_cartProvider.cartQty == 1 ? 'Item' : 'Items'}',
style:
TextStyle(color: Colors.white, fontSize: 14)),
Text(
' | ',
style: TextStyle(color: Colors.white),
),
Text('Rs.${_cartProvider.subTotal}',
style:
TextStyle(fontSize: 18, color: Colors.white)),
],
),
],
),
),
Here is the Provider i've used
class CartProvider with ChangeNotifier {
final CartServices _cart = CartServices();
double subTotal = 0.0;
int cartQty = 0;
QuerySnapshot? snapshot;
List cartList = [];
Future<double?> getCartTotal() async {
var cartTotal = 0.0;
List _newList = [];
QuerySnapshot snapshot =
await _cart.cart.doc(_cart.user!.uid).collection('products').get();
if (snapshot == null) {
return null;
}
snapshot.docs.forEach((doc) {
if (!_newList.contains(doc.data())) {
_newList.add(doc.data());
cartList = _newList;
notifyListeners();
}
cartTotal = cartTotal + doc['total'];
});
subTotal = cartTotal;
cartQty = snapshot.size;
this.snapshot = snapshot;
notifyListeners();
return cartTotal;
}
}
I am not exactly sure what went wrong in this as i've just started in flutter and firebase.
You might want to check what documents you are listening to. From what you say, your app may still be listening to the old user's document and thus you see no change.
P.S.: I believe you should provide a minimal piece of code to recreate the issue you are facing and using pictures is not a very good way. You should try to add the code here as text instead.

How to generate and validate a list of TextEditingController and upload the List of textEditingController to firebase -flutter

I created an upload page where user picks multiple images and then assign a price for each image.I'm want to achieve this with a list of TextEditing controllers and displaying textfield under each image.
First I created the list and later generate the list according to the length of the images.
List<TextEditingController> _controller;
Widget buildGridView() {
return Container(
height: 400,
child: GridView.count(
crossAxisCount: 1,
scrollDirection: Axis.horizontal,
children: List.generate(images.length, (index) {
//I can't use the index I defined below in controller.
//says (i) is undefined so I used the index which defined above.
//Am I doing it right?
_controller = List.generate(images.length, (i) => TextEditingController());
Asset asset = images[index];
return Padding(
padding: EdgeInsets.all(8.0),
child: Container(
height: 100,
width: 100,
child: Column(
children: [
ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(15)),
child: AssetThumb(
asset: asset,
width: 300,
height: 300,
),
),
Form(
key: _formKey,
child: TextFormField(
keyboardType: TextInputType.number,
validator: (String value) {
double sal = double.tryParse(value);
if (sal == null) {
return 'enter or delete row';
}
return null;
},
controller: _controller[index],
),
),
],
),
),
);
}),
),
);
}
Here _formkey gives me error duplicate key found.Can I generate a list of formKeys according to the length of images?
at last I want to upload the list of textEditingControllers. I has .toList() parameter but not .text
You should have just one Form widget with one FormKey and that should wrap the all the TextFormField widgets.
Form class
An optional container for grouping together multiple form field
widgets (e.g. TextField widgets).
https://api.flutter.dev/flutter/widgets/Form-class.html
So in this case, your Form should wrap the GridView.
Here is your buildGridView method with the update:
Widget buildGridView() {
return Container(
height: 400,
child: Form(
key: _formKey,
child: GridView.count(
crossAxisCount: 1,
scrollDirection: Axis.horizontal,
children: List.generate(images.length, (index) {
//I can use the index I defined below in controller.
//says i is undefined so I used the index which defined above.
//Am I doing it right?
_controller =
List.generate(images.length, (i) => TextEditingController());
Asset asset = images[index];
return Padding(
padding: EdgeInsets.all(8.0),
child: Container(
height: 100,
width: 100,
child: Column(
children: [
ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(15)),
child: AssetThumb(
asset: asset,
width: 300,
height: 300,
),
),
TextFormField(
keyboardType: TextInputType.number,
validator: (String value) {
double sal = double.tryParse(value);
if (sal == null) {
return 'enter or delete row';
}
return null;
},
controller: _controller[index],
),
],
),
),
);
}),
),
),
);
}
In order to get the list of text from the controller list, you need to map each controller to get the text.
List<String> textList = _controller.map((x) => x.text).toList();

How to control a RatingBar?

I'm trying to control a RatingBar, but I'm struggling a bit with that. The problem is that the rating bar doesn't get updated. Here's my code:
Widget _buildBody(videoid) {
double rating = 3;
return Container(
color: Colors.red,
child: Stack(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(3, 7, 0, 0),
child: Align(
alignment: Alignment.topLeft,
child: RatingBarIndicator(
rating: rating,
itemBuilder: (context, index) => InkWell(
onTap: (){
setState(() {
rating=index.toDouble()+1;
});
},
child: Icon(
Icons.star,
color: Colors.amber,
),
),
itemCount: 5,
itemSize: 31.0,
direction: Axis.horizontal,
),
),
),
Align(
alignment: Alignment.topRight,
child: TextButton(
onPressed: () {
letuservoting = true;
setState(() {
rating = 0;
israting = false;
});
dislike(idovvideo, _rating);
},
child: Text(
"Clear",
style: TextStyle(color: Colors.white, fontSize: 20),
),
),
),
],
),
);
}
I set the rating to 3, and then on Clear text button I want to set it to 0, and then again when the user taps 2, it should show 2 stars. At the moment it only shows these 3 stars no matter what I do. How can I fix that?
It's better not to assign the variable inside the widget because it keeps rebuilding and it will reassign the variable, in your case the rating variable will keep reassigning to 3. Try to put it in your class, outside the build method.

How do I generate a list of widgets from firebase firestore database?

I'm trying to figure out how to iterate through documents in firestore and create a text widget for each one.
I've figured out how to access those elements. I used debugPrint() and got the results I'm expecting, but I can't get it to display below my other widgets. I get a red screen with a ton of errors (on phone).Below is my code for what I've tried so far.
QuerySnapshot querySnapshot = await
Firestore.instance.collection("users").document(user.uid).collection("trails").getDocuments();
var list = querySnapshot.documents;
list.forEach((doc) => debugPrint(doc.data["Trail Name"].toString()));//works
final topContentText = Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
//these widgets are generating correctly
Text(
"First Name: $firstName",
style: TextStyle(color: Colors.white, ),
),
Text(
"Last Name: $lastName",
textAlign: TextAlign.left,
style: TextStyle(color: Colors.white,),
),
Text(
"Email: $email",
style: TextStyle(color: Colors.white, ),
),
//these ones are causing my errors.
list.forEach((doc) => Text(
"Trail Name: ${doc.data["Trail Name"].toString()}",
style: TextStyle(color: Colors.white, ),
),)
],
);
final topContent = Stack(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height * 0.40,
padding: EdgeInsets.all(40.0),
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(color: Color.fromRGBO(58, 66, 86, .9)),
child: Center(
child: topContentText,
),
),
Positioned(
left: 8.0,
top: 60.0,
child: InkWell(
onTap: () {
Navigator.pop(context);
},
child: Icon(Icons.arrow_back, color: Colors.white),
),
)
],
);
return Scaffold(
body: Column(
children: <Widget>[topContent, bottomContent],
),
);
The screen on my device lights up red with errors on creating child widgets, when I'm expecting it to display the Trail Name(s) below the other info. I only included necessary code, but could include more (such as the widget's build method) if needed. Thanks for any assistance. I'm new to flutter.
Try using the map function:
List<Widget> _widgets = list.map((doc) => Text(
"Trail Name: ${doc.data["Trail Name"].toString()}",
style: TextStyle(color: Colors.white, ),
),).toList();
And then for the children of the column, just add that list to the list you specify, like:
children: [ ... ] + _widgets;

overflowing RenderFlex flutter

I am trying to make a seemingly easy page with flutter.
It contains of totally five rows where row 1 & 2, 3 & 4 belongs together, and the last row is its own.
Row 1: Centered text
Row 2: 8 icon buttons
Row 3: Centered text
Row 4: 5 checkboxes
Row 5: Text with a following icon button
The problem I get is the size:
I/flutter (22610):◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢
A RenderFlex overflowed by 248 pixels on the right.
I have tried to make the code in different classes, according to their belonging, but then I get this error.
When I tried to put the code in containers, the iconButtons and checkBoxes quit working. I have read a lot of questions about similar problems here on Stackoverflow and googled around about it, but I'm still stuck.
class MyIcon extends StatefulWidget {
#override
_MyIconState createState() => _MyIconState();
}
class _MyIconState extends State<MyIcon> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.red,
// body: Container(
// height: 180.0,
// color: Colors.lightBlueAccent,
body: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 50.0),
),
Text(
'FIRST TEXT',
textDirection: TextDirection.ltr,
style: TextStyle(
fontSize: 25.0,
color: Colors.white,
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
// Padding(padding: EdgeInsets.only(left: 3.0, right: 10.0)),
_IconButtons(
headImageAssetPath: 'assets/ico.png',
onPressed: () {},
),
_IconButtons(
headImageAssetPath: 'assets/ico.png',
onPressed: () {},
),
_IconButtons(
headImageAssetPath: 'assets/ico.png',
onPressed: () {},
),
_IconButtons(
headImageAssetPath: 'assets/ico.png',
onPressed: () {},
),
_IconButtons(
headImageAssetPath: 'assets/ico.png',
onPressed: () {},
),
_IconButtons(
headImageAssetPath: 'assets/ico.png',
onPressed: () {},
),
_IconButtons(
headImageAssetPath: 'assets/ico.png',
onPressed: () {},
),
_IconButtons(
headImageAssetPath: 'assets/ico.png',
onPressed: () {},
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"SECOND TEXT'",
style: TextStyle(fontSize: 25.0, color: Colors.white),
),
],
),
MyCheckBox(),
],
),
// ),
);
}
}
class _IconButtons extends StatelessWidget {
final iconSize = 60.0;
final String headImageAssetPath;
final onPressed;
_IconButtons({this.headImageAssetPath, this.onPressed});
#override
Widget build(BuildContext context) {
return IconButton(
iconSize: iconSize,
icon: Image.asset(headImageAssetPath),
onPressed: () {});
}
}
class MyCheckBox extends StatefulWidget {
#override
_MyCheckBoxState createState() => _MyCheckBoxState();
}
class _MyCheckBoxState extends State<MyCheckBox> {
#override
Widget build(BuildContext context) {
return Expanded(
child: Column(
children: <Widget>[
Expanded(
child: Row(
children: <Widget>[
Text(
"ANOTHER TEXT",
textDirection: TextDirection.ltr,
style: TextStyle(
fontSize: 25.0,
color: Colors.blueGrey,
),
),
],
),
),
],
),
);
}
}
This is one of many tries. If you want I can send the code for the checkboxes too. (I'm new to flutter so I'm sorry if my code is bad).
Any help is appreciated. Thank you.
In the row 2, every button icon width valued 60, then the Row container will width valued 60 * 8 = 480 at least, so the error occurs.
I have two solutions for you:
If you want to keep the button size width valued 60, you can replace Row with Wrap, the button will start a new row when it meet the edge of the screen.
If you want the 8 buttons placed in one single row, you can wrap the IconButton with Expanded
return Expanded(child:IconButton(
iconSize: iconSize,
icon: Image.asset(headImageAssetPath),
onPressed: () {}
));

Resources