AlertCardWidget is a widget that i wrote. I return it in itemBuilder but nothing shown. Here is my code:
Flexible(
child: Padding(
child: SingleChildScrollView(
child: ListView.builder(
itemCount: state.data.length,
itemBuilder: (BuildContext context, int index) {
state.data["datas"].map<Widget>((f) {
return AlertCardWidget(
positionId: "${f["8020074"]}",
shipowner: "${f["8020076"]}",
customer: "${f["8020170"]}",
salesRepresenter: "${f["8020176"]}",
operationRepresenter: "${f["8020177"]}",
textContentFontColor:
AppTheme(Theme.of(context).brightness)
.cardFontBackgroundColor,
textfont: Colors.redAccent,
);
}).toList();
},
),
),
),
),
No error to show.
I have items that why I use ListView. The problom of using Listview instead ListView.builder is taking "Vertical viewport was given unbounded height error". The problem has solved when writing Listview like child of Expanded widget. Here is my code:
Expanded(
child: Padding(
padding: const EdgeInsets.all(4.0),
child: ListView(
children: state.data["datas"].map<Widget>((f) => AlertCardWidget(positionId: "${f["8020074"]}",
shipowner: "${f["8020076"]}",
customer: "${f["8020170"]}",
salesRepresenter: "${f["8020176"]}",
operationRepresenter: "${f["8020177"]}",
textContentFontColor: AppTheme(Theme.of(context).brightness).cardFontBackgroundColor,
textfont: Colors.redAccent,)).toList(),
),
),
),
Maybe a silly question, but why are you mapping a list into a ListView.builder?
Have you tried using the index for each iteration instead?
Because what I understand from that code is that every ["datas"] item you've got will generate the whole list for as many times as state.data.length has.
Maybe try this out:
Flexible(
child: Padding(
child: SingleChildScrollView(
child: ListView.builder(
itemCount: state.data.length,
itemBuilder: (BuildContext context, int index) {
return AlertCardWidget(
positionId: state.data[index]["datas"]["8020074"],
shipowner: state.data[index]["datas"]["8020076"],
customer: state.data[index]["datas"]["8020170"],
salesRepresenter: state.data[index]["datas"]["8020176"],
operationRepresenter: state.data[index]["datas"]["8020177"],
textContentFontColor:
AppTheme(Theme.of(context).brightness)
.cardFontBackgroundColor,
textfont: Colors.redAccent,
);
},
),
),
),
),
If that doesn't work, would you mind showing us which data are you trying to retrieve?
Your itemBuilder function does not return a value.
Edit: It should return a single Widget for every entry in your list.
Something like this should work.
Also, Padding Widget is missing the padding property.
Flexible(
child: Padding(
child: SingleChildScrollView(
child: ListView.builder(
itemCount: state.data.length,
itemBuilder: (BuildContext context, int index) {
final f = state.data[index];
return AlertCardWidget(
positionId: "${f["8020074"]}",
shipowner: "${f["8020076"]}",
customer: "${f["8020170"]}",
salesRepresenter: "${f["8020176"]}",
operationRepresenter: "${f["8020177"]}",
textContentFontColor:
AppTheme(Theme.of(context).brightness)
.cardFontBackgroundColor,
textfont: Colors.redAccent,
);
},
),
),
),
),
Related
I want to show Listview underneath my two widgets but when i hot reload, nothing happens and if i run again, UI shows blank screen. If i remove Listview.builder it works fine.
Below is my code.
import 'package:flutter/material.dart';
import 'package:plant_clone/constants.dart';
import 'package:plant_clone/model/model.dart';
import 'package:plant_clone/screens/home/components/header_with_searchbox.dart';
import 'package:plant_clone/screens/home/components/title_with_more_btn.dart';
import 'package:plant_clone/viewmodel/recommended_plants_viewmodel.dart';
class Body extends StatelessWidget {
RecommendedPlantViewModel recommendedPlantViewModel =
new RecommendedPlantViewModel();
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
recommendedPlantViewModel.setWidgetsData();
return SingleChildScrollView(
child: Column(
children: [
HeaderWithSearchBox(size: size),
TitleWithMoreButton(
title: "Recommended",
press: () {},
),
ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 3,
itemBuilder: (context, index) {
return Card(
child: ListTile(
onTap: (){},
title: Text('Hello'),
),
);
})
],
),
);
}
}
It doesn't look like there's any other way than setting height constraint using a SizedBox that's wrapping a ListView.
Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
height: size.height,
child: ListView.builder(
...
),
),
],
)
https://flutter.dev/docs/cookbook/lists/horizontal-list
i think it happened because the list view should have a height,,
the esiest way is to test that put it inside a container and give a height to it..
and the second way is wrap the listview inside a Expanded widget and it will fix ..
if not then post the error from debug log
In order to make this to work, you must wrap your ListView with a Container and define the height property as it is part of a Column. You also need to wrap the widget returned by the itemBuilder with a Container and define the width property as the scrollDirection is set to Axis.horizontal.
Container(
height: 100,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 3,
itemBuilder: (context, index) {
return Container(
width: 100,
child: Card(
child: ListTile(
onTap: () {},
title: Text('Hello'),
),
),
);
},
),
)
I have a list of days, and a list of opening hours for each day.
I need to make the list of days scrollable, and the list of opening hours expands as necessary (= I don't want the list of opening hours to be scrollable into a defined height container).
How to make the list scrollable ?
Here is what I have so far, a list of days that is not scrollable (and I can't see sunday) :
SingleChildScrollView(
child: ListView.builder(
itemCount: _days.length,
itemBuilder: (context, i) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.all(18.0),
child: Text(_days[i],
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.grey[700]))),
Container(
decoration: BoxDecoration(color: Colors.white),
child: ListView.builder(
shrinkWrap: true,
itemCount: _daysDispos[i].length,
itemBuilder: (context, j) {
final dispo = _daysDispos[i][j];
return ListTile(
title: Text(dispo.address.line));
}),
)
],
);
})),
EDIT
In the first listView builder, add :
physics: NeverScrollableScrollPhysics()
Solved my issue.
A good solution would be using Expandable package, and add multiple Expandables inside a single ListView.
Another Solution would be replacing the outer ScrollView with one single ListView, whose Childs will be 7 Columns, each column contains a group of opening hours.
You can try CustomScrollView with multiple SliverLists for your purposes instead of using SingleChildScrollView:
Widget build(BuildContext context) {
return CustomScrollView(
slivers: <Widget>[
SliverList(
delegate: SliverChildListDelegate([
Column(
children: <Widget>[
//Widgets you want to use
],
),
]),
),
SliverList(
delegate: SliverChildListDelegate([
Column(
children: <Widget>[
//Widgets you want to use
],
),
]),
),
],
);
}
I am trying to create an app with a scroll view and the objects are clickable like the google news app. Can anyone answer how to animate the container to have a white glow on holding the tile?
Here is the list view builder I have for the app
Container(
padding: EdgeInsets.only(top: 16),
child: ListView.builder(
physics: ClampingScrollPhysics(),
itemCount: article.length,
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemBuilder: (context, index) {
return news_tile(
imageurl: article[index].urlToimage,
news_title: article[index].title,
news_desc: article[index].description,
web_url: article[index].url
);
}),
)
and this is the contents of the tile which the list view builder calls
class news_tile extends StatelessWidget {
String imageurl, news_title, news_desc,web_url;
news_tile({this.imageurl, this.news_title, this.news_desc,this.web_url});
Widget build(BuildContext context) {
return GestureDetector(
onTap: (){
Navigator.push(context, MaterialPageRoute(
builder: (context) => article_view(
web_url: web_url,
)
));
},
child: Container(
margin: EdgeInsets.only(bottom: 16),
child: Column(
children: <Widget>[
ClipRRect(borderRadius: BorderRadius.circular(6), child: Image.network(imageurl)),
SizedBox(
height: 8,
),
Text(news_title, style: TextStyle(fontSize: 17,fontWeight: FontWeight.w600)),
SizedBox(
height: 8,
),
Text(news_desc, style: TextStyle(color: Colors.black54))
],
),
),
);
}
}
You could go with the InkWell Widget. It provides a tapping/holding color effect similar to that. Have a look at the official docs here:
https://api.flutter.dev/flutter/material/InkWell-class.html
Note that you need a Material Widget as an ancestor of your InkWell, but the docs explain that more.
Hope it works for you!
Edit: Sorry, since you are working with a Container, Ink is also important for you:
https://api.flutter.dev/flutter/material/Ink-class.html
Check the docs section "The ink splashes aren't visible!" for why that is.
I'm aiming for a page that looks like this -
ListView
[Profile _ Image] {Swiper}
[SizedBox]
[Profile Detail-1 ]{Text}
[Profile Detail-2 ]{Text}
[Profile Detail-3 ]{Text}
[Profile Detail-N ] {Text}
I looked at the Flutter cookbook example of MultiList
The cookbook expects all items in the listview to implement the same class. What if this is not possible.
I have tried using index of ListViewBuilder to return Widget based on index.
Is that the right approach? Shall I be doing something completely different - like siglechildScrollView?
Thanks!
Edit1-
Current Code that I'm using -
return NotificationListener<ScrollNotification>(
onNotification: (ScrollNotification scrollInfo) {
if (scrollInfo.metrics.pixels == scrollInfo.metrics.maxScrollExtent) {
this._feedBloc.loadMore();
}
return false;
},
child: ListView.builder(
padding: EdgeInsets.only(bottom: 72),
itemCount: this._postItems.length + 1,
itemBuilder: (context, index) {
if (this._postItems.length == index) {
if (this._isLoadingMore) {
return Container(
margin: EdgeInsets.all(4.0),
height: 36,
width: 36,
child: Center(
child: CircularProgressIndicator(),
),
);
} else {
return Container();
}
}
if(index==0){
return WdgtProfileImage();}
else if(index==1){
return SizedBox(2.0);}
return WdgtUserPost(
model: this._postItems[index],
onPostClick: onPostClick,
);
//return postItemWidget(
// postItem: this._postItems[index], onClick: onPostClick);
}),
);
You can use a CustomScrollView instead of the normal Listview.builder. The CustomScrollView takes in a list of slivers to which you can pass/use a SliverList to build a list.
CustomScrollView(
slivers: <Widget>[
//A sliver widget that renders a normal box widget
SliverToBoxAdapter(
child: WdgtProfileImage(),
),
//A sliver list
SliverList(
//With SliverChildBuilderDelegate the items are constructed lazily
//just like in Listview.builder
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return WdgtUserPost(
model: _postItems[index],
onPostClick: onPostClick,
);
},
childCount: _postItems.length,
),
),
if (_isLoadingMore)
//your loading widget shown at the bootom of the list
SliverToBoxAdapter(
child: Container(
margin: EdgeInsets.all(4.0),
height: 36,
width: 36,
child: Center(
child: CircularProgressIndicator(),
),
),
),
],
)
Additional links to docs:
SliverList
SliverChildBuilderDelegate
SliverToBoxAdapter
Click Here for Image! Click here to see error when i input 'itemCount' I want to ask, I am having trouble using the List.builder () feature. where I can't limit the data contained in the list so that it will display an error message about the error range. Here is the source code that I gave.
_sort = <Sort>[
Sort(
category: 'By Games',
item: new Container(
height: 200,
child: new Container(
child: ListView.builder(
scrollDirection: Axis.vertical,
//itemCount: allGames['games'].length,
itemBuilder: (context, index) {
return Container(
child: Padding(
padding: const EdgeInsets.all(15),
child: Text(allGames['games'][index]['game_title'].toString(), style: new TextStyle(color: Colors.white)),
),
);
},
)))),
and here i call the 'Category' and 'Item'. I wrap it in a wrap widget. then for categories, I did divide it into 3 parts. then every part in the category I named 'items' and the problem is the items here have excess capacity so that the data displayed is leftover and not on target.
child: Wrap(
children: <Widget>[
ListView.builder(
shrinkWrap: true,
itemCount: 3,
itemBuilder: (context, index) {
context = context;
if (index < 2) {
final sort = _sort[index];
return ExpansionTile(
title: ListTile(
title: Text(
sort.category,
style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
),
),
children: <Widget>[
ListTile(
title: sort.item,
)
],
);
} else {
),
You're accessing allGames["games"] and it says that you're trying to use [] on null.
Seems like allGames is null, so put an eye on that.
Other than that, your use of itemCount is fine!
You can add some null awareness by doing something like this:
itemCount = allGames != null ? (allGames["games"]?.length ?? 0) : 0
I think when the build method runs at the first time, your allGames is null. So, try to add a default value, for example:
itemCount: allGames['games'].length ?? 0