How to set null case in Gridview builder - flutter

I am trying to create a container and write no data found in case the data coming from the API is null.
Although I deleted the link of the API, the container does not appear.
body: Obx(
() => fGames2SecScreenLoad.isLoading.value
? const Center(
child: LoadingWidget(),
)
: GridView.builder(
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: (itemWidth / itemHeight),
crossAxisCount: 1,
),
scrollDirection: Axis.vertical,
itemCount: freeGameTypeController.freeGames.length,
itemBuilder: (BuildContext context, int index) {
var freeGames = freeGameTypeController.freeGames[index];
if(freeGamesController.freeGamesList.isEmpty){
return Container(chid: Text("No data found");}
else{
return Padding(
padding: EdgeInsets.symmetric(
horizontal: 7.w,
vertical: 8.h,
),
child: GestureDetector(
onTap: () {
Get.to(
const FreeGamesIndex(),
transition: Transition.native,
duration: const Duration(milliseconds: 200),
arguments: freeGames,
);
},
child: FreeGamesListCard(
fImage: freeGames.image,
fTitle: freeGames.title,
fPlatforms: freeGames.platforms,
fWorth: freeGames.worth,
),
),
);
}}),
),

Try this:
body: Obx(
() => fGames2SecScreenLoad.isLoading.value
? const Center(
child: LoadingWidget(),
)
: Builder(
builder: (_){
if(freeGamesController.freeGamesList.isEmpty){
return Container(chid: Text("No data found");
}
return GridView.builder(
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: (itemWidth / itemHeight),
crossAxisCount: 1,
),
scrollDirection: Axis.vertical,
itemCount: freeGameTypeController.freeGames.length,
itemBuilder: (BuildContext context, int index) {
var freeGames = freeGameTypeController.freeGames[index];
return Padding(
padding: EdgeInsets.symmetric(
horizontal: 7.w,
vertical: 8.h,
),
child: GestureDetector(
onTap: () {
Get.to(
const FreeGamesIndex(),
transition: Transition.native,
duration: const Duration(milliseconds: 200),
arguments: freeGames,
);
},
child: FreeGamesListCard(
fImage: freeGames.image,
fTitle: freeGames.title,
fPlatforms: freeGames.platforms,
fWorth: freeGames.worth,
),
),
);
}),
),
}),
),

Related

get 2 images next to each other instead of 1 in listviewbuilder

I'm trying to get the 2 images next to each other instead of beneath each other but I have no clue how to go about something like this, I tried something with an I variable to influence the index but that did not really work out. normally I could do this but with the index, I have no clue how to go about this.
code:
Center(
child: Column(
children: [
_items.isNotEmpty
? Expanded(
child: ListView.builder(
itemCount: _items.length,
itemBuilder: (context, index) {
return Column(
children: [
RawMaterialButton(
child: Image(
image: NetworkImage(_items[index]["portrait"]),
height: 200,
width: 140,
),
onPressed: () {
Navigator.push(context, _AnimatedNavigation(SpecificCharacterRoute(
_items[index]["name"], _items[index]["name"], _items[index]["shop_background"], _items[index]["overview"],
_items[index]["difficulty"], "images/dbdsurvivorlogo.png")
)
);
},
),
],
);
},
),
)
: Container()
],
),
),
Here's an image of what I mean
Here's an image of what I have
You can use GridView.count( with crossAxisCount: 2,
GridView.count(
crossAxisCount: 2,
children: [...],
);
Or with .builder
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
itemCount: ,
itemBuilder: (context, index) {...},
);
You can use Gridview for 2 in a row. If you want to change from 2 to 3 in row then you can change crossAxisCount.
GridView.builder(
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200,
crossAxisCount: 2,
childAspectRatio: 3 / 2,
crossAxisSpacing: 20,
mainAxisSpacing: 20),
itemCount: _items.length,
itemBuilder: (BuildContext ctx, index) {
return Column(
children: [
RawMaterialButton(
child: Image(
image: NetworkImage(_items[index]["portrait"]),
height: 200,
width: 140,
),
onPressed: () {
Navigator.push(context, _AnimatedNavigation(SpecificCharacterRoute(
_items[index]["name"], _items[index]["name"], _items[index]["shop_background"], _items[index]["overview"],
_items[index]["difficulty"], "images/dbdsurvivorlogo.png")
)
);
},
),
],
);
}),

ListView.builder not working with more elements on tablets

Listview works perfectly fine on mobile and it tablets when there are less than 8 items ( the 2nd row in the picture ) but when I generate more items it doesn't work ( 1st row with the red thing in the picture).I tried giving the container width too but it didnt work as well.
Container(
width: pageWidth - 40,
height: 50,
alignment: Alignment.center,
margin: EdgeInsets.only(
top: pageHeight * 0.02,
),
decoration: boederDailyQHomePage,
child: const Text("سوال روزانه"),
), // box for daily question
const SizedBox(
height: 10,
),
//test categories list
TitleWidget(
text: "تست ها",
onPressed: () {
pushNewScreen(context,
screen: TestsPage(
initialIndex: 0,
),
withNavBar: true);
}),
Container(
height: 180,
padding: const EdgeInsets.only(right: 7),
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext ctx, int index) {
return TestCategoryHomePage(
testName: Provider.of<TestCategoriesData>(context,
listen: false)
.testCategoryData[index],
testImage: testCategoriesImageData[index],
initialIndex: index,
);
},
itemCount: Provider.of<TestCategoriesData>(context,
listen: false)
.testCategoryData
.length
),
),
const SizedBox(
height: 5,
),
//educations list
TitleWidget(
text: "مقاله ها",
onPressed: () {
pushNewScreen(context,
screen: const EducationsPage(), withNavBar: true);
},
),
Container(
height: 180,
padding: const EdgeInsets.only(right: 7),
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext ctx, int index) {
return EducationWidgetHomePage(
education: Provider.of<EducationData>(context,
listen: false)
.educationData[index]);
},
itemCount:
Provider.of<EducationData>(context, listen: false)
.educationData
.length),
),
This is the picture

Why is my StreamController not triggering on scroll? Flutter

We have a gridview.builder showing thumbnails which on tap lead to videos in a gridview. We have a streamcontroller that should trigger as you hit the bottom of the page, load a block (12 thumbnails a time). We wanted to make The whole page scroll. But now the streamcontroller doesn't trigger. If I remove the Neverscrollable physics from the gridview.builder it will trigger.
So in short, I want to be able to scroll the entire page, profile information and then through the ever loading video thumbnails. I am stuck as to why this isn't working. How do I make the streamcontroller trigger with the entire page able to scroll? Help appreciated.
SingleChildScrollView(
controller: _scroller,
physics: ScrollPhysics(),
child: Container(
height: MediaQuery.of(context).size.height,
child: StreamBuilder<List<Post>>(
stream: _streamController,
builder: (context, snapshot) {
return Column(
children: <Widget>[
_buildProfileInfo(_profileUser),
Divider(),
Flexible(
child: GridView.builder(
controller: _scrollController,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
childAspectRatio: 1.0,
mainAxisSpacing: 2.0,
crossAxisSpacing: 2.0,
),
itemCount: _posts.length + 1,
itemBuilder: (BuildContext context, int index) {
if (index == _posts.length) {
if (!_hasMorePosts) {
return SizedBox.shrink();
} else {
return Center(
child: Container(
child: SpinKitThreeBounce(
color: HexColor(hexColorMmRed),
size: 30,
),
));
}
} else {
Post post = _posts[index];
return _buildTilePost(post);
}
},
),
)
],
);
}),
),
);
Container(
height: MediaQuery.of(context).size.height,
child: StreamBuilder<List<Post>>(
stream: _streamController,
builder: (context, snapshot) {
return SingleChildScrollView(
controller: _scroller,
child: Column(
children: <Widget>[
_buildProfileInfo(_profileUser),
Divider(),
GridView.builder(
shrinkWrap: true,
primary: false,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
childAspectRatio: 1.0,
mainAxisSpacing: 2.0,
crossAxisSpacing: 2.0,
),
itemCount: _posts.length + 1,
itemBuilder: (BuildContext context, int index) {
if (index == _posts.length) {
if (!_hasMorePosts) {
return SizedBox.shrink();
} else {
return Center(
child: Container(
child: SpinKitThreeBounce(
color: HexColor(hexColorMmRed),
size: 30,
),
));
}
} else {
Post post = _posts[index];
return _buildTilePost(post);
}
},
)
],
),
);
}),
);
Answer found here

Flutter: FloatingActionButton over last element of GridView

I have a scrollable list with a FloatingActionButton. I would like to make the list to finish before the FloatingActionButton because the last item of the list isn't visible anymore just like in the Gmail application.
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
backgroundColor: Colors.white,
resizeToAvoidBottomInset: false,
appBar: AppBar(
brightness: Brightness.light,
elevation: 0.0,
backgroundColor: Colors.transparent,
title: Text(
'OnePictura',
style: TextStyle(color: dark, fontSize: 20),
),
actions: [
Padding(
padding: const EdgeInsets.all(8),
child: Container(
decoration:
BoxDecoration(shape: BoxShape.circle, color: textWhite),
child: IconButton(
icon: Image.asset(
'graphics/setting_icon.png',
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => new SettingPage(),
),
);
},
),
),
),
],
),
body: LoadingIndicatorPage(
loading: _loading,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Align(
alignment: Alignment.topLeft,
child: IconButton(
icon: ImageIcon(
AssetImage("graphics/icon_search.png"),
),
onPressed: () {
showSearch(context: context, delegate: DataSearch(albumList, _userId));
},
),
),
xyz(),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
var result = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => new CreateAlbumPage(),
),
);
if (result) {
_getAllAlbum();
setState(() {
albumList.clear();
});
}
},
backgroundColor: Colors.white,
child: Icon(
Icons.add,
color: purpleishBlueTwo,
),
),
);
}
Widget xyz() {
if (albumList.length == 0) {
return Expanded(
child: SmartRefresher(
onRefresh: _onRefresh,
controller: _refreshController,
enablePullDown: true,
enablePullUp: false,
child: Center(
child: Text(_message),
),
),
);
} else {
return Expanded(
child: SmartRefresher(
onRefresh: _onRefresh,
controller: _refreshController,
enablePullDown: true,
enablePullUp: false,
child: GridView.builder(
controller: _scrollController,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: MediaQuery.of(context).size.width /
(MediaQuery.of(context).size.height / 1.5),
),
itemCount: albumList.length,
itemBuilder: (BuildContext context, int index) {
return buildRow(index);
},
),
),
);
}
}
Widget buildRow(int index) {
return Padding(
padding: EdgeInsets.only(top: 10.0, right: 10.0, left: 10.0, bottom: 10.0),
child: GestureDetector(
onTap: () async {
var result = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
new AlbumPage(tabIndex: index, albumList: albumList),
),
);
if (result) {
_getAllAlbum();
_getSubscriptionDetails();
setState(() {
albumList.clear();
});
}
},
child: AlbumTile(
index: index,
currentUser: _userId,
albumList: albumList,
deleteAlbum: _deleteDialog,
),
),
);
}
child: GridView.builder(
controller: _scrollController,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: MediaQuery.of(context).size.width /
(MediaQuery.of(context).size.height / 1.5),
),
itemCount: albumList.length,
itemBuilder: (BuildContext context, int index) {
return buildRow(index);
},
),
to
child: GridView.builder(
controller: _scrollController,
padding: EdgeInsets.only(bottom: 70),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: MediaQuery.of(context).size.width /
(MediaQuery.of(context).size.height / 1.5),
),
itemCount: albumList.length,
itemBuilder: (BuildContext context, int index) {
return buildRow(index);
},
),

How to render ListView.builder and GridView.builder on one page

I want to rend ListView.builder and GridView.builder on one page i tried this code but working
difficulty in rendring these two builders both will display vertical list and scrollable.
Scaffold(
appBar: AppBar(title: Text("Title")),
body: Column(
children: <Widget>[
ListView.builder(
primary: false,
shrinkWrap: true,
itemBuilder: (context, position) {
return ListTile(
title: Text(choices[position]),
);
},
itemCount: choices.length,
),
GridView.builder(
physics: ScrollPhysics(),
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: (3 / 2),
),
itemCount: personas.length,
itemBuilder: (BuildContext context, int index) {
return Container(
child: Card(
child: Center(
child: Text(personas[index]?.fullName),
),
),
);
}),
],
),
);
Wrap them in containers and give them proper height or width.
Scaffold(
appBar: AppBar(title: Text("Title")),
body: Column(
children: <Widget>[
Container(
height:200,
child: ListView.builder(
primary: false,
shrinkWrap: true,
itemBuilder: (context, position) {
return ListTile(
title: Text(choices[position]),
);
},
itemCount: choices.length,
),
),
Container(
height:200,
child: GridView.builder(
physics: ScrollPhysics(),
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: (3 / 2),
),
itemCount: personas.length,
itemBuilder: (BuildContext context, int index) {
return Container(
child: Card(
child: Center(
child: Text(personas[index]?.fullName),
),
),
);
}),
)
],
),
);
Wrap Column with SingleChildScrollView which will resolve the rendering issue. Add
physics: ScrollPhysics(), which will allow ListView and GridView to scroll vertically
Scaffold(
appBar: AppBar(title: Text("Title")),
body: SingleChildScrollView(
child: Column(
children: <Widget>[
ListView.builder(
shrinkWrap: true,
physics: ScrollPhysics(),
itemBuilder: (context, position) {
return ListTile(
title: Text('List Item'),
);
},
itemCount: 20,
),
GridView.builder(
physics: ScrollPhysics(),
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: (3 / 2),
),
itemCount: 15,
itemBuilder: (BuildContext context, int index) {
return Container(
child: Card(
child: Center(
child: Text('Grid Item'),
),
),
);
}),
],
),
),
);
Output:
i found the solution this can done by using slivers
Scaffold(
appBar: AppBar(title: Text(appBarTitle)),
body: CustomScrollView(
slivers: <Widget>[
SliverList(
delegate: SliverChildBuilderDelegate((context, index) {
return ListTile(
title: Text(title(choices[index])),
selected: isSame(choices[index], selected),
onTap: () {
onSelected(choices[index]);
},
);
}, childCount: choices.length),
),
SliverToBoxAdapter(
child: GridView.builder(
physics: ScrollPhysics(),
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: (3 / 2),
),
itemCount: personas?.length ?? 0,
itemBuilder: (BuildContext context, int index) {
return Container(
child: Card(
child: Center(
child: Text(personas[index]?.fullName),
),
),
);
}),
),
],
));