How to arrange the items correctly in flutter - flutter

I try to make design of page of display comment. I need make page design is as follows: list at up and then Text Field at the bottom.So user will can see all comment and send new comment.
Something like photo:
but I have same problem with display.
This is my code:I make it like that now but now I can see list just without text field at the bottom
#override
Widget build(BuildContext context) {
return FutureBuilder<List<Flowerdata>>(
future: fetchFlowers(),
builder: (context, snapshot) {
if (!snapshot.hasData) return Center(
child: CircularProgressIndicator()
);
return ListView(
children: snapshot.data
.map((data) => Column(children: <Widget>[
GestureDetector(
onTap: ()=>{
getItemAndNavigate(data.id, context)
},
child: Row(
children: [
Container(
width: 100,
height: 100,
margin: EdgeInsets.fromLTRB(10, 0, 10, 0),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child:
Image.network(data.flowerImageURL,
width: 200, height: 100, fit: BoxFit.cover,))),
Flexible(child:
Text(data.flowerName,
style: TextStyle(fontSize: 18))
),
]),),
Divider(color: Colors.black),
],))
.toList(),
);
Container(
width: 280,
padding: EdgeInsets.all(10.0),
child: TextField(
controller: naameController,
autocorrect: true,
decoration: InputDecoration(hintText: 'Enter Your Name Here'),
)
);
},
);
}
How can I arrange the items correctly?

First, your Container widget is unreachable, you should fix it then you can wrap your widgets with Column and wrap ListView with Expanded widget after giving height to Container. It will fix your problem.
But i have some suggestions about ListView. Why you did not use ListView.separated? If you use separated method you can delete map and your Divider.
Also when i looked your design, your list items looks like a card. You can use Card widget beside of GestureDetector.
I hope this will help you, if not i will glad to help you.
Edit: Here is sample code based on your question and my answer;
Column(
children: [
Expanded(
child: ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int i) {
InkWell(
onTap: () => getItemAndNavigate(snapshot.data[i].id, context),
child: Card(
child: Row(
children: <Widget>[
Container(
width: 100,
height: 100,
margin: EdgeInsets.fromLTRB(10, 0, 10, 0),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: Image.network(snapshot.data[i].flowerImageURL,
width: 200, height: 100, fit: BoxFit.cover,),
),
),
Flexible(
child: Text(
snapshot.data[i].flowerName,
style: TextStyle(fontSize: 18),
),
),
]
),
),
);
},
),
),
Container(
width: 280,
padding: EdgeInsets.all(10.0),
child: TextField(
autocorrect: true,
decoration: InputDecoration(hintText: 'Enter Your Name Here'),
),
),
],
),

You are placing the TextField in the position after returning ListView, which make it dead code. You can add it at the end of your ListView children list or place a Stack outside to place both the ListView and TextField inside.

Related

Efficient way to make container take remaining width in a Row widget in Flutter

I am new to Flutter and was practicing its UI where I came across a situation where I had a list where each list element have an image on the left and some text on right.
Below is my approach to that
child: ListView(
padding: const EdgeInsets.symmetric(horizontal: 20),
children: [
const SizedBox(height: 5),
Row(
children: [
Container(
height: 80,
width: 80,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
image: const DecorationImage(
image: NetworkImage('http://images.unsplash.com/photo-1555010133-d883506aedee?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max'),
fit: BoxFit.cover
)
),
),
const SizedBox(width: 10),
Container(
color: Colors.green,
height: 80,
width: 280,
)
],
),
],
),
Here I am specifying width individually for both containers which is not an efficient way to do this since phone sizes may vary.
Below is the result for above block of code
Screenshot of the app screen
I tried specifying crossAxisAlignment: CrossAxisAlignment.stretch to the Row() but it throws an error as below
The following assertion was thrown during performLayout():
BoxConstraints forces an infinite height.
How can I achieve this? Please assist
Thank you
Wrap the widget with an Expanded inside the row:
Row(
children: [
...otherChildren,
Expanded(
child: Container(
color: Colors.green,
height: 80,
),
),
],
),
Use ListView.builder with ListTile widgets. It has a leading widget (normally an icon or an avatar) to the left, text in the middle and trailing widget (normally an icon), each of which is optional.
ListView.builder(
itemCount: ...,
itemBuilder: (BuildContext context, int index) {
return ListTile(
leading: const CircleAvatar(
radius: 20.0,
foregroundImage: NetworkImage(...),
),
title: Text(...),
subtitle: Text(...),
trailing: ...,
onTap: () => ...,
);
},
)

it's possible to make listview in expand and fill parent without overflow?

it's possible to make listview in expand and fill the container without overflow the container, and shrink when listview is short of content without declare manual min or max height?
Code
Flexible(
fit: FlexFit.loose,
child: Container(
padding: EdgeInsets.symmetric(vertical: 20, horizontal: 10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(kBoxRadius),
boxShadow: [kBoxShadow]),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
DText(
"Aug 2021",
size: 12,
weight: FontWeight.bold,
),
SizedBox(height: 10),
Row(
children: dates,
),
SizedBox(height: 15),
Container(
height: 1,
color: Color(0xFFE7E7E7),
),
Container(
constraints:
BoxConstraints(minHeight: 0, maxHeight: 600),
child: ListView.separated(
shrinkWrap: true,
itemBuilder: (context, index) {
return DText("Asd");
},
separatorBuilder: (_, __) {
return SizedBox(height: 10);
},
itemCount: 20,
),
)
],
),
),
)
Expectation
when the content is big
because i set manually max height.
Yes, it is possible using shrinkWrap: true. The code will be something like below,
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(),
body: Center(
child: Container(
color: Colors.red,
child: ListView(
shrinkWrap: true,
children: <Widget>[
ListTile(title: Text('Apple')),
ListTile(title: Text('Orange')),
ListTile(title: Text('Banana')),
],
),
),
),
),
);
}
}

Listview.builder not showing my images when implementing in Flutter

I am trying to implement a horizontal Listview which shows my images pulled from the Flutter image_picker plugin.
its work fine if I do not use a Listview and only display a single image. however I am trying to use multiple images and as soon as I place within the Listview the widgets just shows up as black. my code for the Listview is as follows:
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
Navigator.pushReplacementNamed(context, 'inventory');
return false;
},
child: Scaffold(
appBar: AppBar(
backgroundColor: Colors.green[700],
title: Text(
'MyApp',
textAlign: TextAlign.center,
),
leading: new IconButton(
icon: new Icon(Icons.arrow_back),
onPressed: () {
Navigator.pushReplacementNamed(
context,
'inventory');
},
),
actions: <Widget>[
Padding(
padding: EdgeInsets.only(right: 10.0),
child: Container(
width: 50,
height: 50,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.white, //remove this when you add image.
),
child: GestureDetector(
onTap: (){
Navigator.pushNamed(context,'profile');
},
child: Image(
image:NetworkImage("imageUrl goes here"),
width: 120,
height: 120,
fit: BoxFit.cover,
),
),
),
)
],
),
body: SafeArea(
child: Column(
children: [
pickedFile == null ?
GestureDetector(
onTap: () {
_showMyDialog();
setState(() {
});
},
child: Container(
width: 200,
height: 200,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Click to add a Photo',textAlign:
TextAlign.center,style: TextStyle(fontSize: 24),),
SizedBox(height: 20,),
Icon(
Icons.add_circle_outline,
color: Colors.grey[700],
size: 30,
),
],
),
margin: EdgeInsets.all(20.0),
decoration: BoxDecoration(
border: Border.all(width: 2,color: Colors.grey),
shape: BoxShape.circle
),
),
)
:
GestureDetector(
onTap: () {
_showMyDialog();
setState(() {
});
},
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: _imageFileList!.length,
itemBuilder: (BuildContext context, int index) {
return kIsWeb
? Image.network(_imageFileList![index].path)
: Image.file(File(_imageFileList!
[index].path));
}
)
],
),
),),
);
}
}
I am not showing the whole code as the page is too long however the rest of the page works fine. if i remove the Listview builder and instead test using just the below it works fine. what am i doing wrong?
child: Row(
children: [
kIsWeb
? Container(
child: Image.network(_imageFileList![index].path))
: Container(
child: Image.file(File(_imageFileList![index].path)));
}
),
],
),
Please help.
**Edited the above code with my full widget
Either use Row or use ListView, not both.
You can use Row with List.generate:
Row(
children: List.generate(_imageFileList!.length,
(i) => kIsWeb
? Container(child: Image.network(_imageFileList![index].path))
: Container(child: Image.file(File(_imageFileList![index].path))
),
Or ListView exactly how you have it without the Row. ListView is probably the widget you’re wanting to use. Row will overflow if the content is larger than the width while ListView will act as its own ScrollView in that situation.
I’d also double-check that you need that Expanded widget. That’s typically for use inside a Row (or similar widgets).
Managed to solve my issue. it was related to a height constraint which needed to be added. found the solution in this link
How to add a ListView to a Column in Flutter?

flutter widget hides behind keyboard when it opens

I am trying to create a chat screen with text field at the bottom and whenever it is clicked the keyboard comes up and the textfield should be on top of the keyboard but my own isn't doing what it's supposed to do. I have checked other similar questions and answers on google, stackoverflow and github but it still stays the maybe because in mine am using constraints: BoxConstraints(maxHeight: 160), which might be what is causing it but i don't really know
This my code
class _ChatSectionState
extends State<ChatSectionState> {
List<File> images = List<File>();
getMultiFile() async {
await pickFileFromMobile("multi").then((value) {
if (value != null) {
value.paths.forEach((element) {
images.add(File(element));
});
// images = value.paths.map((path) => File(path)).toList();
}
});
setState(() {});
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(...,
body: Container(
height: double.infinity,
child: Stack(
children: [
Padding(
padding: EdgeInsets.only(bottom: 50),
child: Container(
child: ListView.builder(
itemCount: 10,
reverse: true,
shrinkWrap: true,
physics: ScrollPhysics(),
itemBuilder: (ctx, idx) {...
///...
),
),
),
///This is the part that hides behide the keyboard when it appears which i want to show on top
Align(
alignment: Alignment.bottomCenter,
child: Container(
decoration: BoxDecoration(
color: white,
border: Border(
top: BorderSide(
color: grey[400],
width: .7,
),
bottom: BorderSide(
color: grey[400],
width: .7,
)),
),
constraints: BoxConstraints(maxHeight: 160), //This is the box contraints
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
(images.length < 1)
? SizedBox(height: 0)
: Expanded(
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
physics: ScrollPhysics(),
padding: EdgeInsets.symmetric(
vertical: 7, horizontal: 10),
itemCount: images.length,
itemBuilder: (ctx, idx) {
return Container(
///... This is to show a image from file width a height of 100
);
},
),
),
Container(
decoration: BoxDecoration(
border: Border(
top: BorderSide(
color: grey[300],
width: .5,
)),
),
child: Row(children: [
Container(
margin: new EdgeInsets.symmetric(horizontal: 8.0),
child: new IconButton(
icon: new Icon(Icons.image),
onPressed: () => getMultiFile(),
color: primary,
),
),
Flexible(
child: Container(
child: TextFormField(
//controller: messageEditingController,
style: TextStyle(color: nBlack, fontSize: 15.0),
decoration: InputDecoration.collapsed(
hintText: 'Type a message',
hintStyle: TextStyle(color: grey),
),
onFieldSubmitted: (value) {},
),
),
),
Container(
margin: new EdgeInsets.symmetric(horizontal: 8.0),
child: new IconButton(
icon: new Icon(Icons.send),
onPressed: () {},
color: primary,
),
),
]),
),
],
),
),
)
],
),
),
resizeToAvoidBottomInset: false,
));
}
}
Please how can I make it work cause i have checked different pages still does give me what i want. I also tried this [answer][1]
[1]: https://stackoverflow.com/a/49715952/14650702 which worked but the animation was terrible
You can change resizeToAvoidBottomInset: ture, for scaffold.
it will shrink the whole scaffold when keyboard is opened.
I use another way. resizeToAvoidBottomInset: true and do some changes for lifting widgets top of keyboard.
bottom = MediaQuery.of(context).viewInsets.bottom;
Scaffold(
resizeToAvoidBottomInset: ture,
body: SingleChildScrollView(
reverse:true,
child: Padding(
padding: EdgeInsets.only(bottom: bottom),
child: ...
)));
if you decrease space from keyboard to last widget use MediaQuery.of(context).viewInsets.bottom/2 e.x.

Problem to separate listView.Builder into two lines

I've been trying to modify my flutter code to display product-categories on two lines.
In the current model, you can view the categories without any problem by dragging them to the side (only one line). However, for ease of future customer-viewer, I would like to split it into two lines.
my current ListView.builder displays like this:
Click Here
I would like it to display as follows: Click Here
Here is my code:
Row(
children: [
Expanded(
child: SizedBox(
height: 80,
child: category.categoryList != null ? category.categoryList.length > 0 ? ListView.builder(
itemCount: category.categoryList.length,
padding: EdgeInsets.only(left: Dimensions.PADDING_SIZE_SMALL),
physics: BouncingScrollPhysics(),
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return Padding(
padding: EdgeInsets.only(right: Dimensions.PADDING_SIZE_SMALL),
child: InkWell(
onTap: () => Navigator.pushNamed(context, Routes.getCategoryRoute(
category.categoryList[index].id, category.categoryList[index].image,
category.categoryList[index].name.replaceAll(' ', '-'),
)),
child: Column(children: [
ClipOval(
child: FadeInImage.assetNetwork(
placeholder: Images.placeholder_image,
image: Provider.of<SplashProvider>(context, listen: false).baseUrls != null
? '${Provider.of<SplashProvider>(context, listen: false).baseUrls.categoryImageUrl}/${category.categoryList[index].image}':'',
width: 65, height: 65, fit: BoxFit.cover,
),
),
Text(
category.categoryList[index].name,
style: rubikMedium.copyWith(fontSize: Dimensions.FONT_SIZE_SMALL),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
]),
),
);
},
) : Center(child: Text(getTranslated('no_category_avl', context))) : CategoryShimmer(),
),
),
ResponsiveHelper.isMobile(context)? SizedBox(): category.categoryList != null ? Column(
children: [
InkWell(
onTap: (){
showDialog(context: context, builder: (con) => Dialog(
child: Container(height: 550, width: 600, child: CategoryPopUp())
));
},
child: Padding(
padding: EdgeInsets.only(right: Dimensions.PADDING_SIZE_SMALL),
child: CircleAvatar(
radius: 35,
backgroundColor: Theme.of(context).primaryColor,
child: Text(getTranslated('view_all', context), style: TextStyle(fontSize: 14,color: Colors.white)),
),
),
),
SizedBox(height: 10,)
],
): CategoryAllShimmer()
],
),
If anyone can help me, I will be very grateful. Big hug!
There are 2 possibilities I can think of
Solution 1:
You can have 2 list views one on the top and one on the bottom. (1st row having half and the 2nd row having another half)
First row: itemCount: half, and inside builder you can use index as it is
Second row: itemCount: half, and inside builder you can use index as index+half (as builder always starts from 0)
*Above solution might be a tough choice if you have the category items more than 10 (which again leads to scrolling)
Solution 2:
You can use a "GridView"
Below is a link where you can go through to know how you can build in GridView.
Link: https://stackoverflow.com/a/44184514/10136829
Hope this answers is helpful.