I need to change this ListView to GridView Flutter - flutter

I need to change this ListView to GridView Flutter .Thanks
#override
Widget build(BuildContext context) {
return Consumer<ShopCategoryModel>(
builder: (_, model, __) => ListView.separated(
shrinkWrap: true,
separatorBuilder: (_, index) => const Divider(),
itemBuilder: (_, index) => model.isGettingCategories
? _catLoadingItem()
: _catItem(model.categories[index]),
itemCount: model.isGettingCategories ? 5 : model.categories.length,
),
);
}

I have done minor modification to show it as a grid. Though if it is not as per you, please share the design you want to achieve.
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: MediaQuery.of(context).orientation ==
Orientation.landscape ? 3: 2,
crossAxisSpacing: 8,
mainAxisSpacing: 8,
)
itemCount:model.isGettingCategories ? 5 : model.categories.length,
shrinkWrap: true,
itemBuilder: (_,index,) => model.isGettingCategories
? _catLoadingItem()
: _catItem(model.categories[index]),
)

Use Widget GridView for list Item and rebuild UI when change
var _isListView = true;
#override
Widget build(BuildContext context) {
return Column(
children: [
TextButton(
onPressed: () {
setState(() {
_isListView = !_isListView
});
},
child: Text("Switch"),
),
Consumer<ShopCategoryModel>(
builder: (_, model, __) =>
_isListView ? ListView.separated() : GridView.builder(),
)
],
);
}

Related

i want to add a row in listview.builder but it goes blank

i want to add a row ( list of buttons that do filter the list), i tried wrapping listTile in column, listview.builde in column but it doesn't work. tried wrapping GetBuilder also but it doesn't work.
enter image description here
My Code :-
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:quizzy/data_controller.dart';
import '../models/showQuestion.dart';
class AllQuestionBank extends StatefulWidget {
const AllQuestionBank({Key? key}) : super(key: key);
#override
State<AllQuestionBank> createState() => _AllQuestionBankState();
}
class _AllQuestionBankState extends State<AllQuestionBank> {
final DataController controller = Get.put(DataController());
#override
Widget build(BuildContext context) {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
controller.getQuestionList();
});
return Scaffold(
appBar: AppBar(
title: const Text(' Question Bank'),
),
body: GetBuilder<DataController>(
builder: (controller) => controller.QuestionList.isEmpty
? const Center(
child: Text('😔 NO DATA FOUND (: 😔'),
)
: ListView.builder(
itemCount: controller.QuestionList.length,
itemBuilder: (context, index) {
return ListTile(
title: showQuestion(controller.QuestionList[index]),
);
}),
),
);
}
}
You could redefine your ListView as:
ListView.builder(
itemCount: controller.QuestionList.length + 1,
itemBuilder: (context, index) {
if (index == 0) {
return WhateverRowYouWant();
}
return ListTile(
title: showQuestion(controller.QuestionList[index - 1]),
);
}),
You can just define the scroll direction to be horizontal.
ListView.builder(
itemCount: controller.QuestionList.length,
scrollDirection: Axis.horizontal, <- added this line
itemBuilder: (context, index) {
return ListTile(
title: showQuestion(controller.QuestionList[index]),
);
}),
You can also find an example from the official docs here
Try this.
physics: NeverScrollableScrollPhysics(), shrinkWrap: true,
To add Row() on top you need Column() widget for sure
After that, you have to wrap ListView.builder() with the Expanded() widget this will help you
Ex.
return Scaffold(
body: SafeArea(
child: Column(
children: [
Row(
children: [
TextButton(
onPressed: () {},
child: Text('Filter'),
),
],
),
Expanded(
child: GetBuilder<DataController>(
builder: (controller) => controller.QuestionList.isEmpty
? const Center(
child: Text('😔 NO DATA FOUND (: 😔'),
)
: ListView.builder(
shrinkWrap: true,
itemCount: controller.QuestionList.length,
itemBuilder: (context, index) {
return ListTile(
title: showQuestion(controller.QuestionList[index]),
);
},
),
),
),
],
),
),
);
Please, try this!!
This is the combination of GetxController and ListView with a top row I use:
class MyController extends GetxController {
var isRunning = true.obs; // set to isRunning.value = false; if done loading QuestionList
RxList<ProductModel> QuestionList = <ProductModel>[].obs;
}
Obx( () => controller.isRunning.isTrue
? 'Loading'
: ListView.builder(
itemCount: controller.QuestionList.length + 1,
itemBuilder: (BuildContext context, int index) {
if (index == 0) {
return Text('TOP ROW');
}
return ListTile(
title: showQuestion(controller.QuestionList[index - 1]),
);
}),
);

I need to change categories layout like this Flutter

I need to change categories layout like this Flutter
Its code of Multi Vendor - Flutter woocommerce app :
code:
class _ShopCategoryScreenState extends State<ShopCategoryScreen> {
void _toShopList(Category cat) {
final model = Provider.of<ShopCategoryModel>(context, listen: false);
model.setCatId(cat.id!);
model.getProducts();
Navigator.of(context).push(MaterialPageRoute(
builder: (_) => ShopProductListScreen.category(
name: cat.name,
ctx: context,
)));
}
Widget _catItem(Category cat) {
return InkWell(
onTap: () => _toShopList(cat),
child: Column(
children: [
Text(
cat.name ?? '',
style: Theme.of(context).textTheme.subtitle1,
),
],
),
);
}
#override
Widget build(BuildContext context) {
return Consumer<ShopCategoryModel>(
builder: (_, model, __) => GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: MediaQuery.of(context).orientation ==
Orientation.landscape ? 3: 2,
crossAxisSpacing: 8,
mainAxisSpacing: 8,
),
itemBuilder: (_, index) => model.isGettingCategories
? _catLoadingItem()
: _catItem(model.categories[index]),
itemCount: model.isGettingCategories ? 5 : model.categories.length,
),
);
}
}
Please help to change above code to same image that i shared ..thanks

How to implement checkbox over GridView correctly

I have checkbox for selecting and deselecting photos.
There is a visible loading screen for each tap.
_mediaList has the photo asset. mediaModel has the necessary methods to add and remove the path of selected and deselected photos respectively.
Widget build(BuildContext context) {
super.build(context);
return GridView.builder(
itemCount: _mediaList.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3, mainAxisSpacing: 4.0, crossAxisSpacing: 4.0),
itemBuilder: (BuildContext context, int index) {
final saved = mediaModel.getMedia().contains(
_mediaList[index].relativePath + '/' + _mediaList[index].title);
return FutureBuilder(
future: _mediaList[index].thumbDataWithSize(200, 200),
builder: (BuildContext context, snapshot) => snapshot.hasData
? GridTile(
header: saved
? Icon(Icons.check_circle, color: Colors.white,)
: Icon(Icons.check_circle_outline, color: Colors.white,),
child: GestureDetector(
child: Image.memory(
snapshot.data,
fit: BoxFit.cover,
),
onTap: () => setState(() => saved
? mediaModel.removeMedia(
_mediaList[index].relativePath +
'/' +
_mediaList[index].title)
: mediaModel.addMedia(
_mediaList[index].relativePath +
'/' +
_mediaList[index].title))),
)
: Container());
},
);
}
EDIT: After some analysis, I found out using Provider to load images might be the right way.
Can you help me in converting this code to Provider?
Thanks in advance!!!
Screenshot:
Full code:
class FooPage extends State<SoPage> {
static const int _count = 10;
final List<bool> _checks = List.generate(_count, (_) => false);
#override
Widget build(BuildContext context) {
return Scaffold(
body: GridView.builder(
itemCount: _count,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
itemBuilder: (_, i) {
return Stack(
children: [
Container(color: Colors.red[(i * 100) % 900]),
Align(
alignment: Alignment.topCenter,
child: Checkbox(
value: _checks[i],
onChanged: (newValue) => setState(() => _checks[i] = newValue),
),
),
],
);
},
),
);
}
}

ScrollController not working without a container

I have a ScrollController in my page to work with infinite scroll but when the list builder is not in a Container the ScrollController listeners does not work.
Works
Container(
height: 400,
child: Observer(
builder: (_) {
return ListView.builder(
shrinkWrap: true,
controller: _scrollController,
itemCount: passeiosController.passeios.length,
itemBuilder: (_, index) => PasseioCard(
passeioModel: passeiosController.passeios[index],
),
);
},
),
)
Not working
Observer(
builder: (_) {
return ListView.builder(
shrinkWrap: true,
controller: _scrollController,
itemCount: passeiosController.passeios.length,
itemBuilder: (_, index) => PasseioCard(
passeioModel: passeiosController.passeios[index],
),
);
},
)
It worked. I had a list view builder inside a listview. Putting the controller in the parent listview worked correctly.

How to Implement Progress Indicator in Flutter

I am trying to implement a Progress Indicator in Flutter but I am not sure whether I need to put in the if condition to show Progress Indicator while the item is still Loading.
class HomePageNewArrival extends StatefulWidget {
final List<Product> productList;
HomePageNewArrival({this.productList});
#override
_HomePageNewArrivalState createState() => _HomePageNewArrivalState();
}
class _HomePageNewArrivalState extends State<HomePageNewArrival> {
#override
Widget build(BuildContext context) {
return Container(
height: 550,
child: GridView.builder(
physics: NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 2 / 3.2,
crossAxisSpacing: 1,
mainAxisSpacing: 1,
),
itemCount: this.widget.productList.length,
itemBuilder: (context, index) {
if (index.) {
return HomenewArrivalProducts(this.widget.productList[index]);
} else {
return new CircularProgressIndicator();
}
}),
);
}
}
Building widgets in flutter is instant
i think what you wanna do is to show a circular spinner while images are loading in HomenewArrivalProducts() Widget if you have a Image.network() try this:
child: Image.network(
'https://example.com/image.jpg',
loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent loadingProgress) {
if (loadingProgress == null)
return child;
return Center(
child: CircularProgressIndicator(
value: loadingProgress.expectedTotalBytes != null
? loadingProgress.cumulativeBytesLoaded / loadingProgress.expectedTotalBytes
: null,
),
);
},
),
and if you wanna just to make an illusion of something is loading you can use FutureBuilder()
FutureBuilder(
future: Future.delayed(Duration(milliseconds: 500)),
builder: (ctx, snapshot) =>
snapshot.connectionState == ConnectionState.waiting
? CircularProgressIndicator()
: GridView.builder(...),
);