How to do a GridView with two crossAxisCount in Flutter? - flutter

This is the example of expected output
For the first row, the crossAxisCount will be 3 and the second row, the crossAxisCount will be 2.
GridView.builder(
physics: NeverScrollableScrollPhysics(),
gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
childAspectRatio: 0.75,
mainAxisSpacing: 2.0,
crossAxisSpacing: 1.0,
),
itemCount: int.parse(snapshot.data.result[num].collected),
itemBuilder:
(BuildContext context, int i) {
return Image.asset(
'assets/coin.png');
}),

You can set crossAxisCount to 1 and childAspectRatio to number you need, I use 2
In itemBuilder check index is Odd and return Row with 2 or 3 asset icon
You can copy paste run full code below
code snippet
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1, childAspectRatio: 2),
itemCount: _icons.length,
itemBuilder: (context, index) {
if (index.isOdd) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
child: Image.asset('assets/coin.png'),
),
Container(
child: Image.asset('assets/coin.png'),
),
Container(
child: Image.asset('assets/coin.png'),
),
],
);
} else {
working demo
full code
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(flex: 1, child: InfiniteGridView()),
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
class InfiniteGridView extends StatefulWidget {
#override
_InfiniteGridViewState createState() => new _InfiniteGridViewState();
}
class _InfiniteGridViewState extends State<InfiniteGridView> {
List<IconData> _icons = [];
#override
void initState() {
_retrieveIcons();
}
#override
Widget build(BuildContext context) {
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1, childAspectRatio: 2),
itemCount: _icons.length,
itemBuilder: (context, index) {
if (index.isOdd) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
child: Image.asset('assets/coin.png'),
),
Container(
child: Image.asset('assets/coin.png'),
),
Container(
child: Image.asset('assets/coin.png'),
),
],
);
} else {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
child: Image.asset('assets/coin.png'),
),
Container(
child: Image.asset('assets/coin.png'),
),
],
);
}
});
}
void _retrieveIcons() {
Future.delayed(Duration(milliseconds: 200)).then((e) {
setState(() {
_icons.addAll([
Icons.ac_unit,
Icons.airport_shuttle,
Icons.all_inclusive,
Icons.beach_access,
Icons.cake,
Icons.free_breakfast
]);
});
});
}
}

Related

Add Notification Badge for particular grid in flutter?

How to add notification badge for particular index.
I was created a Grid suing Gridview.builder now I want to add notification badge on 3 rd index(All List Count) of grid list I don't know how to add in particular list
This is my code:
import 'package:flutter/material.dart';
class StudentView extends StatefulWidget {
const StudentView({Key? key}) : super(key: key);
#override
State<StudentView> createState() => _StudentViewState();
}
class _StudentViewState extends State<StudentView> {
var notificationDetailsList = [];
List category = [
'Fruits',
'Grocery',
'Vegetable',
'All List Count',
'Notification',
];
#override
Widget build(BuildContext context) {
// print(notlength);
return Container(
child: Center(
child: GridView.builder(
itemCount: catergory.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, childAspectRatio: 5 / 2),
itemBuilder: (BuildContext context, int index) {
return Card(
color: Colors.blue.shade100,
child: Center(child: Text(catergory[index])));
})),
);
}
}
You can try this method and replace my condition with your condition.
import 'package:badges/badges.dart';
import 'package:flutter/material.dart';
class StudentView extends StatefulWidget {
const StudentView({Key? key}) : super(key: key);
#override
State<StudentView> createState() => _StudentViewState();
}
class _StudentViewState extends State<StudentView> {
var notificationDetailsList = [];
List category = [
'Fruits',
'Grocery',
'Vegetable',
'All List Count',
'Notification',
];
#override
Widget build(BuildContext context) {
// print(notlength);
return Scaffold(
appBar: AppBar(),
body: Center(
child: GridView.builder(
itemCount: category.length,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, childAspectRatio: 5 / 2),
itemBuilder: (BuildContext context, int index) {
return Stack(
clipBehavior: Clip.none,
children: [
Card(
color: Colors.blue.shade100,
child: Center(
child: Text(
category[index],
),
),
),
index.isEven
? Positioned(
right: 0,
top: -6,
child: Badge(
badgeContent: const Text('3'),
),
)
: const SizedBox.shrink(),
],
);
},
),
),
);
}
}

How to scroll a ListView inside a Column that inside a BottomSheet

I have a ListView inside a Column inside a BottomSheet like this
I want to scroll ListView without affecting Container that contains Text("Text No Scroll")
So pls help me, this is my code so far:
import 'package:flutter/material.dart';
import 'package:get/get.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return GetMaterialApp(
home: Scaffold(
appBar: AppBar(),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () => Get.bottomSheet(
GetXBottomSheet(),
backgroundColor: Colors.white,
isScrollControlled: true,
),
),
),
);
}
}
class GetXBottomSheet extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
constraints: BoxConstraints(maxHeight: Get.height * 0.7),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
child: Text('Text No Scroll', textAlign: TextAlign.center),
color: Colors.grey,
width: double.infinity),
ListView.separated(
separatorBuilder: (__, _) => Divider(height: 0),
itemCount: List<int>.generate(100, (i) => i).length,
shrinkWrap: true,
physics: ScrollPhysics(),
itemBuilder: (BuildContext context, int index) {
return Text('$index');
},
),
],
),
);
}
}
From the code that you have provided I have created an example that will fulfil your requirement.
Key Points:
For the bottom sheet you have :
give the alignment for the container of text so that it will be fixed.
Add an expanded widget to the list view so that it can scroll
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(home: MyApp()));
}
class MyApp extends StatefulWidget {
MyApp({Key key}) : super(key: key);
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
void _modalBottomSheetMenu() {
showModalBottomSheet(
context: context,
builder: (builder) {
return Container(
constraints: BoxConstraints(
maxHeight: MediaQuery.of(context).size.height * 0.7),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
alignment: Alignment.topCenter,
child: Text('Text No Scroll', textAlign: TextAlign.center),
color: Colors.grey,
width: double.infinity),
Expanded(
child: ListView.separated(
separatorBuilder: (__, _) => Divider(height: 0),
itemCount: List<int>.generate(100, (i) => i).length,
shrinkWrap: true,
physics: ScrollPhysics(),
itemBuilder: (BuildContext context, int index) {
return Text('$index');
},
),
),
],
),
);
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () => _modalBottomSheetMenu(),
),
),
);
}
}
Check this out and let me know if it works
Thanks

Flutter Futurebuilder inside TabBarView not triggering the future after initial application load while switching between tabs?

I am new to flutter and trying to implement a tabview in homePage in the flutter app.
The first tab is populated from data from firebase remote config and second tab is populated by using Futurebuilder. When I switch the tabs the future function is not triggering. It is only triggered during initial application load. Whenever I switch tabs and come back to 2nd tab. The futurebuilder's future function is not triggered again.
Can someone give any solutions for this.?
Container(
width: MediaQuery.of(context).size.width,
color: Colors.white,
child: GridView.count(
shrinkWrap: true,
physics: BouncingScrollPhysics(),
padding: const EdgeInsets.all(4.0),
childAspectRatio: 1.0,
crossAxisCount: isTablet ? 2 : 1,
crossAxisSpacing: 4.0,
mainAxisSpacing: 4.0,
children: [
FutureBuilder(
future: _getBookmarks,
builder:
(BuildContext context, AsyncSnapshot snapshot) {
var listWidget;
if (snapshot.connectionState ==
ConnectionState.done) {
if (snapshot.data.length == 0) {
listWidget = Container(
child: Center(
child: Text("No Favorites to Display!"),
));
} else {
listWidget = ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
final bookmarks = snapshot.data[index];
return BuildFavoriteCard(
bookmarks, context);
},
);
}
} else {
listWidget = Center(
child: CircularProgressIndicator(),
);
}
return listWidget;
})
],
))
Here's an example combining the TabBar and FutureBuilder examples of the Flutter documentation.
If you run this, you will see that a new future is created each time you navigate to the first tab (since the TabBarView's content is rebuilt).
I would assume that this is currently not working for you since your future _getBookmarks is defined somewhere higher up in the widget tree (in the part that is not rebuilt by switching tabs).
The solution would be to move the future inside your TabBarView widget.
import 'package:flutter/material.dart';
void main() {
runApp(const TabBarDemo());
}
class TabBarDemo extends StatelessWidget {
const TabBarDemo({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
bottom: const TabBar(
tabs: [
Tab(icon: Icon(Icons.directions_car)),
Tab(icon: Icon(Icons.directions_transit)),
],
),
title: const Text('Tabs Demo'),
),
body: TabBarView(
children: [
Center(
child: MyStatefulWidget(),
),
Icon(Icons.directions_transit),
],
),
),
),
);
}
}
/// This is the stateful widget that the main application instantiates.
class MyStatefulWidget extends StatefulWidget {
MyStatefulWidget({
Key? key,
}) : super(key: key);
#override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
/// This is the private State class that goes with MyStatefulWidget.
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
Future<String>? _calculation;
#override
void initState() {
_calculation = Future<String>.delayed(
const Duration(seconds: 2),
() => 'Data Loaded',
);
super.initState();
}
#override
Widget build(BuildContext context) {
return DefaultTextStyle(
style: Theme.of(context).textTheme.headline2!,
textAlign: TextAlign.center,
child: FutureBuilder<String>(
future:
_calculation, // calculation, // a previously-obtained Future<String> or null
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
List<Widget> children;
if (snapshot.hasData) {
children = <Widget>[
const Icon(
Icons.check_circle_outline,
color: Colors.green,
size: 60,
),
Padding(
padding: const EdgeInsets.only(top: 16),
child: Text('Result: ${snapshot.data}'),
),
];
} else if (snapshot.hasError) {
children = <Widget>[
const Icon(
Icons.error_outline,
color: Colors.red,
size: 60,
),
Padding(
padding: const EdgeInsets.only(top: 16),
child: Text('Error: ${snapshot.error}'),
)
];
} else {
children = const <Widget>[
SizedBox(
child: CircularProgressIndicator(),
width: 60,
height: 60,
),
Padding(
padding: EdgeInsets.only(top: 16),
child: Text('Awaiting result...'),
)
];
}
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: children,
),
);
},
),
);
}
}

Is there a way to push the updated state of data of one stateful widget into another stateful widget?

I have been struggling with the problem of pushing updated data from one widget to another. This problem occurs when I have two Stateful widgets and the data is updated in the parent Stateful widget but is not updated in the child Stateful widget. The error occurs with the usage of the freezed package but also occurs without it as well.
I have not been able to find anything that fixes this as of yet.
Below is an example:
First Stateful Widget:
class FirstWidget extends StatefulWidget {
#override
_FirstWidgetState createState() => _FirstWidgetState();
}
class _FirstWidgetState extends State<FirstWidget> {
ItemBloc _itemBloc = getit<ItemBloc>();
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
elevation: Mquery.width(context, 2.5),
backgroundColor: Colors.black
title: Text(
'First stateful widget',
style: TextStyle(fontSize: 17),
),
centerTitle: true,
),
body: BlocBuilder<ItemsBloc,ItemsState>(
cubit: _itemsBloc,
builder: (BuildContext context,ItemState state) {
return state.when(
initial: () => Container(),
loading: () => Center(child: CustomLoader()),
success: (_items) {
return AnotherStatefulWidget(
items: _items,
...
);
},
);
},
));
},
);
);
}
}
Second Stateful Widget:
class AnotherStatefulWidget extends StatefulWidget {
final List<String> items;
AnotherStatefulWidget(this.items);
#override
_AnotherStatefulWidgetState createState() => _AnotherStatefulWidgetState();
}
class _AnotherStatefulWidgetState extends State<AnotherStatefulWidget> {
final ScrollController scrollController = ScrollController();
ItemsBloc _itemsBloc = getit<ItemsBloc>();
bool _handleNotification(ScrollNotification notification, List<String> items) {
if (notification is ScrollEndNotification &&
scrollController.position.extentAfter == 0.00) {
_itemsBloc.add(ItemsLoadEvent.loadMoreItems(
categories: items, document: ...));
}
return false;
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
body: Container(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: double.infinity,
height: 280,
child: Padding(
padding: EdgeInsets.only(
right: 8,
),
child: NotificationListener<ScrollNotification>(
onNotification: (_n) =>
_handleNotification(_n, widget.items),
child: DraggableScrollbar.arrows(
alwaysVisibleScrollThumb: true,
controller: scrollController,
child: ListView.builder(
controller: scrollController,
itemCount: widget.items.length,
itemBuilder: (context, index) {
return GestureDetector(
child: Padding(
padding: EdgeInsets.all(16),
child: Align(
alignment: Alignment.center,
child: Text(
widget.items[index],
style: TextStyle(color: Colors.white),
)),
),
);
},
),
),
),
),
)
],
),
),
),
);
}
}
I would really appreciate any help!
Thank you for you time,
Matt

Flutter: setState() is invalid for type of List

my brothers! Sorry, my English is terrible, I hope u can unserstand.
I cannot use setState((){}) to update variable of List type! I try to fix this for a long time, but I failed.
This is my demo code, u can run this:
import 'package:flutter/material.dart';
void main() => runApp(TestListUpdate()) ;
class TestListUpdate extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: TestListUpdatePage(),
);
}
}
class TestListUpdatePage extends StatefulWidget {
TestListUpdatePage({Key key}) : super(key: key);
#override
_TestListUpdatePageState createState() => _TestListUpdatePageState();
}
class _TestListUpdatePageState extends State<TestListUpdatePage> {
int _counter = 0;
List<Widget> _list = [];
void _incrementCounter() {
setState(() {
_counter++;
});
}
void _addPic() {
setState(() {
_list.add(
ClipRRect(
borderRadius: BorderRadius.circular(5),
child: Image.network(
'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1581151314271&di=6d55b078b319acc55d081685e3208b6c&imgtype=0&src=http%3A%2F%2Fimg-download.pchome.net%2Fdownload%2F1k1%2Fe0%2F32%2Fol8r6m-1sqx.jpg',
fit: BoxFit.cover,
)),
);
});
print(_list.length);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Test'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
Container(
height: 100,
child: GridView.count(
physics: NeverScrollableScrollPhysics(),
crossAxisCount: 4,
crossAxisSpacing: 5,
mainAxisSpacing: 5,
children: _list,
))
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_incrementCounter();
_addPic();
},
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
when I press add button, the number has changed. But data of grid not change..
Please help me! Thank u!!
move the list initialization to the initState function
change:
List<Widget> _list = [];
to:
List<Widget> _list;
initialize the list in the initState function:
#override
void initState() {
super.initState();
_list = [];
}
You can use "GridView.builder". Your "setState" is working. Not working is "GridView.count".
Container(
height: 100,
child: GridView.builder(
itemBuilder: (context, index) {
return _list[index];
},
itemCount: _list.length,
physics: NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
crossAxisSpacing: 5,
mainAxisSpacing: 5,
),
),
),