Add Notification Badge for particular grid in flutter? - 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(),
],
);
},
),
),
);
}
}

Related

When i update slider in a ListView.Builder it updates all sliders at once

I have a list of sliders in my listview.builder, when I slide one slider, it automatically updates the rest of the sliders with the same value. I want each slider to update its value independently
class ApplyForMeScreen extends StatefulWidget {
const ApplyForMeScreen({Key? key}) : super(key: key);
static const String routeName = "/ApplyForMeScreen";
#override
_AppyForMeScreenState createState() => _AppyForMeScreenState();
}
class _AppyForMeScreenState extends State<ApplyForMeScreen> {
double sliderValue = 20;
final options = ['volume 1','volume 2','volume 3','volume 4','volume 5'];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Slider"),
),
body: Container(
padding: const EdgeInsets.all(20),
child: Column(
children: [
ListView.builder(
physics: const BouncingScrollPhysics(),
shrinkWrap: true,
itemCount: options.length,
itemBuilder: (context, index) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(options[index]),
Slider(
value: sliderValue,
min: 0,
max: 100,
onChanged: (value) => setState(() {
sliderValue = value;
}))
],
);
}),
],
),
),
);
}
}
View Screenshot
View Screenshot
Create a data class with sliderValue and option. Then create a list in this data class object type. Try this code snippet:
import 'package:flutter/material.dart';
class SliderData {
double sliderValue = 0;
String option = "";
SliderData(this.option, this.sliderValue);
}
class ApplyForMeScreen extends StatefulWidget {
const ApplyForMeScreen({Key? key}) : super(key: key);
static const String routeName = "/ApplyForMeScreen";
#override
_AppyForMeScreenState createState() => _AppyForMeScreenState();
}
class _AppyForMeScreenState extends State<ApplyForMeScreen> {
final slidersData = [
SliderData('volume 1', 20),
SliderData('volume 2', 20),
SliderData('volume 3', 20),
SliderData('volume 4', 20),
SliderData('volume 5', 20)
];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Slider"),
),
body: Container(
padding: const EdgeInsets.all(20),
child: Column(
children: [
ListView.builder(
physics: const BouncingScrollPhysics(),
shrinkWrap: true,
itemCount: slidersData.length,
itemBuilder: (context, index) {
var sliderData = slidersData[index];
return Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(sliderData.option),
Slider(
value: sliderData.sliderValue,
min: 0,
max: 100,
onChanged: (value) => setState(() {
sliderData.sliderValue = value;
}),
)
],
);
},
),
],
),
),
);
}
}

How to create a tabbar that sync with a widget scroll in flutter?

Basically what I want to accomplish here is to have a horizontal list of categories(could be TabBar) and a vertical list of the categories with items list in each category.
And when you click on a category it should scroll to a position in the vertical list of categories.
And when you scroll the vertical list, the active category at the top should also update the current active category.
I've seen this function in the FoodPanda app but I am not able to replicate it.
Any suggestions on how can I accomplish this functionality?
Here's the screenshot of the UI.
You can copy paste run full code below
You can use package https://pub.dev/packages/scrollable_list_tabview
code snippet
body: ScrollableListTabView(
tabHeight: 48,
bodyAnimationDuration: const Duration(milliseconds: 150),
tabAnimationCurve: Curves.easeOut,
tabAnimationDuration: const Duration(milliseconds: 200),
tabs: [
ScrollableListTab(
tab: ListTab(
label: Text('Vegetables'),
icon: Icon(Icons.group),
showIconOnList: false),
body: ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: 10,
itemBuilder: (_, index) => ListTile(
leading: Container(
height: 40,
width: 40,
decoration: BoxDecoration(
shape: BoxShape.circle, color: Colors.grey),
alignment: Alignment.center,
child: Text(index.toString()),
),
title: Text('Vegetables element $index'),
),
)),
ScrollableListTab(
tab: ListTab(label: Text('Fruits'), icon: Icon(Icons.add)),
body: ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
working demo
full code
import 'package:flutter/material.dart';
import 'package:scrollable_list_tabview/scrollable_list_tabview.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter ScrollableListTabView Example'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: ScrollableListTabView(
tabHeight: 48,
bodyAnimationDuration: const Duration(milliseconds: 150),
tabAnimationCurve: Curves.easeOut,
tabAnimationDuration: const Duration(milliseconds: 200),
tabs: [
ScrollableListTab(
tab: ListTab(
label: Text('Vegetables'),
icon: Icon(Icons.group),
showIconOnList: false),
body: ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: 10,
itemBuilder: (_, index) => ListTile(
leading: Container(
height: 40,
width: 40,
decoration: BoxDecoration(
shape: BoxShape.circle, color: Colors.grey),
alignment: Alignment.center,
child: Text(index.toString()),
),
title: Text('Vegetables element $index'),
),
)),
ScrollableListTab(
tab: ListTab(label: Text('Fruits'), icon: Icon(Icons.add)),
body: ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: 10,
itemBuilder: (_, index) => ListTile(
leading: Container(
height: 40,
width: 40,
decoration: BoxDecoration(
shape: BoxShape.circle, color: Colors.grey),
alignment: Alignment.center,
child: Text(index.toString()),
),
title: Text('Fruits element $index'),
),
)),
ScrollableListTab(
tab: ListTab(label: Text('Meat'), icon: Icon(Icons.group)),
body: ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: 10,
itemBuilder: (_, index) => ListTile(
leading: Container(
height: 40,
width: 40,
decoration: BoxDecoration(
shape: BoxShape.circle, color: Colors.grey),
alignment: Alignment.center,
child: Text(index.toString()),
),
title: Text('Meat element $index'),
),
)),
ScrollableListTab(
tab: ListTab(
label: Text('Herbs&Spices'), icon: Icon(Icons.subject)),
body: GridView.builder(
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2),
physics: NeverScrollableScrollPhysics(),
itemCount: 10,
itemBuilder: (_, index) => Card(
child: Center(child: Text('Herbs&Spices element $index')),
),
)),
ScrollableListTab(
tab: ListTab(
label: Text('Egg'),
icon: Icon(Icons.subject),
showIconOnList: true),
body: GridView.builder(
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2),
physics: NeverScrollableScrollPhysics(),
itemCount: 10,
itemBuilder: (_, index) => Card(
child: Center(child: Text('Egg element $index')),
),
)),
],
),
);
}
}
I have tried several methods but this seems to be best for me.
Packages:
scroll_to_index: ^2.0.0
rect_getter: ^1.0.0
Usage of rect_getter is inspired by: https://gist.github.com/debuggerx01/49f108d68ed903458e9478b4f0c186f4
Code (Food Panda Clone):
import 'package:flutter/material.dart';
import 'package:scroll_to_index/scroll_to_index.dart';
import 'package:food_panda_sticky_header/colors.dart';
import 'package:food_panda_sticky_header/example_data.dart';
import 'package:food_panda_sticky_header/widgets/widgets.dart';
import 'package:rect_getter/rect_getter.dart';
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> with SingleTickerProviderStateMixin {
bool isCollapsed = false;
late AutoScrollController scrollController;
late TabController tabController;
final double expandedHeight = 500.0;
final PageData data = ExampleData.data;
final double collapsedHeight = kToolbarHeight;
final listViewKey = RectGetter.createGlobalKey();
Map<int, dynamic> itemKeys = {};
// prevent animate when press on tab bar
bool pauseRectGetterIndex = false;
#override
void initState() {
tabController = TabController(length: data.categories.length, vsync: this);
scrollController = AutoScrollController();
super.initState();
}
#override
void dispose() {
scrollController.dispose();
tabController.dispose();
super.dispose();
}
List<int> getVisibleItemsIndex() {
Rect? rect = RectGetter.getRectFromKey(listViewKey);
List<int> items = [];
if (rect == null) return items;
itemKeys.forEach((index, key) {
Rect? itemRect = RectGetter.getRectFromKey(key);
if (itemRect == null) return;
if (itemRect.top > rect.bottom) return;
if (itemRect.bottom < rect.top) return;
items.add(index);
});
return items;
}
void onCollapsed(bool value) {
if (this.isCollapsed == value) return;
setState(() => this.isCollapsed = value);
}
bool onScrollNotification(ScrollNotification notification) {
if (pauseRectGetterIndex) return false;
int lastTabIndex = tabController.length - 1;
List<int> visibleItems = getVisibleItemsIndex();
bool reachLastTabIndex = visibleItems.length <= 2 && visibleItems.last == lastTabIndex;
if (reachLastTabIndex) {
tabController.animateTo(lastTabIndex);
} else {
int sumIndex = visibleItems.reduce((value, element) => value + element);
int middleIndex = sumIndex ~/ visibleItems.length;
if (tabController.index != middleIndex) tabController.animateTo(middleIndex);
}
return false;
}
void animateAndScrollTo(int index) {
pauseRectGetterIndex = true;
tabController.animateTo(index);
scrollController
.scrollToIndex(index, preferPosition: AutoScrollPosition.begin)
.then((value) => pauseRectGetterIndex = false);
}
#override
Widget build(BuildContext context) {
return Scaffold(
extendBodyBehindAppBar: true,
backgroundColor: scheme.background,
body: RectGetter(
key: listViewKey,
child: NotificationListener<ScrollNotification>(
child: buildSliverScrollView(),
onNotification: onScrollNotification,
),
),
);
}
Widget buildSliverScrollView() {
return CustomScrollView(
physics: const ClampingScrollPhysics(),
controller: scrollController,
slivers: [
buildAppBar(),
buildBody(),
],
);
}
SliverAppBar buildAppBar() {
return FAppBar(
data: data,
context: context,
scrollController: scrollController,
expandedHeight: expandedHeight,
collapsedHeight: collapsedHeight,
isCollapsed: isCollapsed,
onCollapsed: onCollapsed,
tabController: tabController,
onTap: (index) => animateAndScrollTo(index),
);
}
SliverList buildBody() {
return SliverList(
delegate: SliverChildListDelegate(
List.generate(data.categories.length, (index) {
itemKeys[index] = RectGetter.createGlobalKey();
return buildCategoryItem(index);
}),
),
);
}
Widget buildCategoryItem(int index) {
Category category = data.categories[index];
return RectGetter(
key: itemKeys[index],
child: AutoScrollTag(
key: ValueKey(index),
index: index,
controller: scrollController,
child: CategorySection(category: category),
),
);
}
}
Demo:
https://github.com/theacheng/food_panda_sticky_header/pull/4

flutter CustomScrollView scroll bug when using multiple SliverStaggeredGrid

Can't scroll when using multiple staggeredgridview
Share my code and screen at the link below
https://github.com/letsar/flutter_staggered_grid_view/issues/98
Please help me
I ran into same issue today. I have an ugly solution.
Add staggeredgridview by rapping it like this.
SliverToBoxAdapter(
child: SizedBox(
height: (products.length/2 + products.length%2) * 245,
child: CustomScrollView(
physics: NeverScrollableScrollPhysics(),
slivers: [
SliverStaggeredGrid.countBuilder()])))
SliverToBoxAdapter are acceptable to CustomScrollview
My Grid using crossAxisCount: 3,,
itemLength/3 can gives fraction. use ~/.
OutPut
Main Widget
import 'package:flutter/material.dart';
import 'package:staggered_grid_view_flutter/widgets/sliver.dart';
import 'package:staggered_grid_view_flutter/widgets/staggered_tile.dart';
class StraggerMUl extends StatelessWidget {
const StraggerMUl({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
int itemsLength = 7;
return Scaffold(
body: LayoutBuilder(builder: (context, constraints) {
return CustomScrollView(
slivers: [
GirdBOx(
constraints: constraints,
itemsLength: itemsLength,
),
GirdBOx(
constraints: constraints,
itemsLength: itemsLength,
),
GirdBOx(
constraints: constraints,
itemsLength: itemsLength,
),
],
);
}),
);
}
}
SliverBox
class GirdBOx extends StatelessWidget {
final BoxConstraints constraints;
final int itemsLength;
const GirdBOx({
Key? key,
required this.itemsLength,
required this.constraints,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return SliverToBoxAdapter(
child: SizedBox(
height: (itemsLength ~/ 3) * (constraints.maxWidth * (1 / 3.0)) +
(itemsLength % 3) * (constraints.maxWidth * (1 / 3.0)),
child: Container(
color: Colors.amber,
child: CustomScrollView(
physics: NeverScrollableScrollPhysics(),
slivers: [
SliverStaggeredGrid.countBuilder(
crossAxisCount: 3,
itemCount: itemsLength,
itemBuilder: (BuildContext context, int index) => Container(
color: Colors.green,
child: Center(
child: CircleAvatar(
backgroundColor: Colors.white,
child: Text('$index'),
),
)),
staggeredTileBuilder: (int index) {
// if (_largeTiles.contains(index))
// return StaggeredTile.count(2, 2);
// else
return StaggeredTile.count(1, 1);
},
mainAxisSpacing: 1.0,
crossAxisSpacing: 1.0,
),
],
),
),
),
);
}
}

Flutter GridView.Builder isn't scrolling (height issues)

I'm trying to make a grid of products using GridView.Builder but it gives error :
Vertical viewport was given unbounded height.
I tried to use flexible on GridView it worked but I need to use GridView.Builder Specifically
and if I tried to wrap it with Flexible or specific height container it doesn't scroll ,any tips?
import 'package:flutter/material.dart';
class Products extends StatefulWidget {
#override
_ProductsState createState() => _ProductsState();
}
class _ProductsState extends State<Products> {
var productList=[
{
"name":"Blazer",
"picture":"images/products/blazer1.jpeg",
"oldPrice":120,
"price":100
},
{
"name":"Dress",
"picture":"images/products/dress1.jpeg",
"oldPrice":120,
"price":100
},
{
"name":"hills",
"picture":"images/products/hills1.jpeg",
"oldPrice":11,
"price":10
},
{
"name":"pants",
"picture":"images/products/pants2.jpeg",
"oldPrice":12,
"price":200,
}
];
#override
Widget build(BuildContext context) {
return GridView.builder(
scrollDirection: Axis.vertical,
itemCount: productList.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
itemBuilder: (context,index){
return SingalProduct(
name: productList[index]['name'],
picture: productList[index]['picture'],
oldPrice: productList[index]['oldPrice'],
price: productList[index]['price'],
);
},
);
}
}
class SingalProduct extends StatelessWidget {
final name,picture,oldPrice,price;
SingalProduct({this.name,this.picture,this.oldPrice,this.price});
#override
Widget build(BuildContext context) {
return Card(
child: Hero(
tag: name,
child: InkWell(
onTap: (){},
child: GridTile(
footer: Container(
height: 40,
color: Colors.white,
child: Padding(
padding: EdgeInsets.fromLTRB(8, 12, 0, 0),
child: Text(name,textAlign: TextAlign.start,style: TextStyle(fontWeight: FontWeight.bold,fontSize: 16),),
),
),
child: Image.asset(picture,fit: BoxFit.cover, ),
),
),
),
);
}
}

How to do a GridView with two crossAxisCount in 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
]);
});
});
}
}