Problem to separate listView.Builder into two lines - flutter

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.

Related

Flutter: Make all screen scrollable with GridView.builder inside

In my home screen my app shows carousel first then a vertical list of challenges cards retrieved from Cloud Firestore using GridView.builder as follows:
GridView.builder(
scrollDirection: Axis.vertical,
itemCount: _challenges.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
childAspectRatio: MediaQuery.of(context).size.width /
(MediaQuery.of(context).size.height / 4),
),
itemBuilder: (context, index) {
return InkWell(
onTap: () {
if (_challenges[index]["isLocked"] == "true") {
showLockedDialog();
} else {
checkParticipation(index);
if (checkPart == true) {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) =>
ChallengeDetails(_challenges[index])));
}
checkPart = true;
}
},
child: Stack(
children: [
Center(
child: ClipRRect(
borderRadius: BorderRadius.circular(15),
child: Image(
image: NetworkImage(_challenges[index]["image-path"]),
fit: BoxFit.cover,
height: 150,
width: 350,
opacity: _challenges[index]["isLocked"] == "true"
? AlwaysStoppedAnimation(.4)
: null,
),
),
),
Center(
child: Text(
"${_challenges[index]["name"]}\n",
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold),
),
),
Center(
child: Text(
"\n${_challenges[index]["date"]}",
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold),
textDirection: TextDirection.ltr,
)),
Center(
child: SizedBox(
height: 130,
width: 130,
child: _challenges[index]["isLocked"] == "true"
? Image.asset("assets/lock-icon.jpg")
: null,
),
)
],
),
);
});
Everything retrieving fine and it is rendered in my home_screen as follows:
body: Column(
children: [
AdsBanner(),
SizedBox(
height: 30,
),
Padding(
padding: const EdgeInsets.only(right: 8, left: 8, bottom: 5),
child: Row(
children: [
Text(
AppLocalizations.of(context)!.challenges + " ",
style: TextStyle(fontSize: 20),
),
Text(
AppLocalizations.of(context)!.clickToParticipate,
style: TextStyle(fontSize: 15),
)
],
),
),
Expanded(child: ChallengeCard()),
],
),
The problem is that only the GridView area is scrolling and what am seeking for is to scroll the whole screen with the GridView area, I was trying to use the CustomScrollView() but its not working properly.
I'll be thankful for any help.
First in your GridView.builder add these:
GridView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
...
)
then in your home_screen wrap your column with SingleChildScrollView:
SingleChildScrollView(
child: Column(
children: [
AdsBanner(),
SizedBox(
height: 30,
),
Padding(
...
),
),
You can provide physics: NeverScrollableScrollPhysics() on GridView to disable scroll effect. If you want scrollable as secondary widget use primary: false, to have Full Page scrollable, you can use body:SingleChildScrollView(..) or better using body:CustomScrollView(..)

set left widget as focused one in flutter

I am using card_swiper widget in my project. It is a good library, but there is a problem: the focused widget always stays on centre but I want the focused item to be the one on the left. How can I accomplish this with this library?
In the below picture, focused item is on centre, but yellow item, in my case, should be on the left.
I found the answer which could be useful for others. The example is for 4 items on view but you can customise it to as many as you want:
Scaffold(
backgroundColor: AppColors.purpleDark,
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Flexible(
child: Swiper(
index: chosenIndex,
layout: SwiperLayout.CUSTOM,
physics: BouncingScrollPhysics(),
customLayoutOption: CustomLayoutOption(
startIndex: 0,
stateCount: math.min(4, listSize),
).addScale(
[3, 1, 1, 1], // there should be 4 widgets in view with the first 3 times larger
Alignment.topRight,
).addTranslate( // place the 4 items as I want
[
Offset(-35.toResizableWidth(), 0),
Offset(30.toResizableWidth(), 0.0),
Offset(118.toResizableWidth(), 0.0),
Offset(200.toResizableWidth(), 0.0),
],
),
itemWidth: 51.toResizableWidth(),
itemHeight: 51.toResizableHeight(),
controller: controller,
itemCount: listSize,
onIndexChanged: (newIndex) => setState(() => chosenIndex = newIndex),
itemBuilder: (context, index) {
return GestureDetector(
onTap: () => controller.next(),
child: Container(
width: 51.toResizableWidth(),
height: 51.toResizableHeight(),
color: Colors.grey,
child: Center(
child: Text(
'$index',
style: AppTextStyles.styleS16W600.copyWith(color: Colors.white),
),
),
),
);
},
),
),
Padding(
padding: EdgeInsets.symmetric(
vertical: 10.toResizableHeight(),
horizontal: 20.toResizableWidth(),
),
child: Text(
LocaleKeys.rewards_day.tr(args: <String>[chosenIndex.toString()]),
style: AppTextStyles.styleS20W600
.copyWith(color: true ? AppColors.greenPositive : AppColors.redNegative),
),
),
Padding(
padding: EdgeInsets.symmetric(
horizontal: 20.toResizableWidth(),
),
child: Text(
longText,
style: AppTextStyles.styleS16W400.copyWith(color: AppColors.white100),
),
),
Expanded(child: Container()),
],
),
);

How to arrange the items correctly in 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.

Flutter Page reloads when keyboard opens or closes

I am working on a chat page using flutter so the page structure is
Container(
color: color,
child: Column(
children: <Widget>[
Flexible(
child: ScrollablePositionedList.builder(
itemScrollController: _itemScrollController,
itemPositionsListener: _itemPositionListener,
initialScrollIndex: _messages.length - 1,
padding: EdgeInsets.all(8.0),
reverse: false,
itemBuilder: (_, int index) => GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
print("tapped");
FocusScope.of(context).requestFocus(new FocusNode());
},
child: ChatMessage(
message: _messages[index],
),
),
itemCount: _messages.length,
),
),
Divider(
height: 1.0,
),
Container(
padding: EdgeInsets.only(bottom: 32, left: 8, right: 8),
decoration: new BoxDecoration(
color: Theme.of(context).cardColor,
),
child: _textComposerWidget(),
)
],
),
);
The problem is when click on textFrom or when keyboard opens or closes the page reloaded and i loss every data in the listView and in the textForm()
Need more info, seems like you are using StatelessWidget instead of Stateful

Flutter How to Display a List of Widgets in a Container

So in my app, I am building a list of widgets, which is basically just a container with text in it.
I am doing this for a variety of reasons, but basically here is where I am having the problem.
I can view this list in a ListView.Builder, but I do not want to view them that way. I want to be able to view them in a container. Then wrap down the container as items get added.
Below is a mock up of what I am trying to do.
Right now my page looks like this.
body: Column(children: <Widget>[
Expanded(
flex: 3,
child: Container(
width: MediaQuery.of(context).size.width*0.8,
child: Row(
children: <Widget>[
Expanded(
child: ListView.builder(
itemCount: hashList.length,
itemBuilder: (context, index){
return Container(
child: hashList[index],
);
}),
)
],
),
),
),
Expanded(
flex: 6,
child: Container(
color: Colors.black,
child: ListView.builder(
itemCount: snapshot.length,
itemBuilder: (context, index) {
return Tag(
callback: (list) => setState(() => hashList = list),
tag: snapshot[index].data["title"],
list: hashList,
id: index,
);
},
)
))]),
And the Tag Widget adds to the list with the following.
void _handleOnPressed() {
setState(() {
isSelected = !isSelected;
isSelected
? _animationController.forward()
: _animationController.reverse();
isSelected ? widget.list.add(
Container(
padding: EdgeInsets.all(10),
height: 45,
child: Text(widget.tag, style: TextStyle(color: Color(0xffff9900), fontSize: 20, fontFamily: 'Dokyo'),),
decoration: BoxDecoration(
border: Border.all(color: Color(0xffff9900),),
borderRadius: BorderRadius.circular(10))
)): widget.list.removeAt(widget.id);
});
}
}
Adding the list to a listview, I can do, but it is not the desired affect.
I have no clue how to do what I am looking for and I am completely lost.
Try and add shrinkWrap to the ListView Builder
child: ListView.builder(shrinkWrap:true, <-- this
.... # then continue your logic