How to set a boundary to the dragging of the Child Widget inside ReorderableListView
Current Output : -
Expected Output : -
Draggable Child Widget should not move further than the blue Container Widget.
Code to reproduce the issue : -
import 'package:flutter/material.dart';
void main() => runApp(const ReorderableApp());
class ReorderableApp extends StatelessWidget {
const ReorderableApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('ReorderableListView Sample')),
body: const ReorderableExample(),
),
);
}
}
class ReorderableExample extends StatefulWidget {
const ReorderableExample({super.key});
#override
State<ReorderableExample> createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<ReorderableExample> {
final List<int> _items = List<int>.generate(20, (int index) => index);
#override
Widget build(BuildContext context) {
return Center(
child: Container(
height: 300,
width: 300,
color: Colors.blue[100],
padding: const EdgeInsets.all(10),
child: Center(
child: ReorderableListView(
padding: const EdgeInsets.symmetric(vertical: 10),
children: <Widget>[
for (int index = 0; index < _items.length; index += 1)
Container(
key: Key('$index'),
height: 60,
margin: const EdgeInsets.all(5),
color: Colors.blue[400],
alignment: Alignment.center,
child: Text('Item ${_items[index]}'),
),
],
onReorder: (int oldIndex, int newIndex) {
setState(() {
if (oldIndex < newIndex) {
newIndex -= 1;
}
final int item = _items.removeAt(oldIndex);
_items.insert(newIndex, item);
});
},
),
),
),
);
}
}
Finally, after lot of research, I found a solution for this requirement with Overlay and OverlayEntry
Here is a code
class _MyStatefulWidgetState extends State<ReorderableExample> {
final List<int> _items = List<int>.generate(20, (int index) => index);
#override
Widget build(BuildContext context) {
return Center(
child: Container(
height: 300,
width: 300,
color: Colors.blue[100],
padding: const EdgeInsets.all(10),
child: Overlay(
initialEntries: [OverlayEntry(
builder: (context) {
return Center(
child: Builder(
builder: (context) {
return ReorderableListView(
padding: const EdgeInsets.symmetric(vertical: 10),
children: <Widget>[
for (int index = 0; index < _items.length; index += 1)
Container(
key: Key('$index'),
height: 60,
margin: const EdgeInsets.all(5),
color: Colors.blue[400],
alignment: Alignment.center,
child: Text('Item ${_items[index]}'),
),
],
onReorder: (int oldIndex, int newIndex) {
setState(() {
if (oldIndex < newIndex) {
newIndex -= 1;
}
final int item = _items.removeAt(oldIndex);
_items.insert(newIndex, item);
});
},
);
}
),
);
}
)],
),
),
);
}
}
Really interesting while work on this kind of task. Thanks #Ramji
Related
I've to use graphql query and I've got data page by page.
so I need to Infinite Scrolling in my list view builder but I don't know how to add num in page.
can anyone help me, please?
this is my query:
query homeview(\$moreId: ID!, \$page: Int! ){
homeview(HM_ID: \$moreId, page: \$page){
HM_ID
HM_Type_ID
HM_Type_Name
}
}
""";
and this is my variable to pass int number in page:
dynamic pageNum = 0;
here is the controller :
ScrollController _scrollController = new ScrollController( initialScrollOffset: 10,
and this is my list view builder:
class MoreEpd extends StatefulWidget {
final String moreId;
const MoreEpd({Key? key, required this.moreId}) : super(key: key);
#override
_MoreEpdState createState() => _MoreEpdState();
}
class _MoreEpdState extends State<MoreEpd> {
double pageWidth = 0;
double pageHeigh = 0;
dynamic pageNum = 0;
final String leftArrow = 'assets/icons/left-arrow.svg';
String getSearchResult = """
query homeview(\$moreId: ID!, \$page: Int! ){
homeview(HM_ID: \$moreId, page: \$page){
HM_ID
Priority
Details{
Ep_ID
Image
title
Pod_title
}
}
}
""";
#override
Widget build(BuildContext context) {
pageWidth = MediaQuery.of(context).size.width;
pageHeigh = MediaQuery.of(context).size.height;
return Container(
child: Query(
options: QueryOptions(
document: gql(getSearchResult),
variables: {'moreId': widget.moreId, 'page': pageNum},
),
builder: (
QueryResult result, {
Refetch? refetch,
FetchMore? fetchMore,
}) {
return handleResult(result);
},
),
);
}
Widget handleResult(QueryResult result) {
var data = result.data!['homeview']['Details'] ?? [];
return Container(
child: ListView.builder(
padding: EdgeInsets.only(top: 15),
shrinkWrap: true,
itemCount: data.length ,
itemBuilder: (context, index) {
return InkWell(
onTap: () {},
child: Padding(
padding: EdgeInsets.only(
top: pageWidth * 0.0,
right: pageWidth * 0.08,
left: pageWidth * 0.08,
bottom: pageWidth * 0.0),
child: Container(
child: Stack(
children: [
Column(
children: [
Padding(
padding:
EdgeInsets.only(bottom: pageWidth * 0.060),
child: Row(
children: [
Padding(
padding:
EdgeInsets.only(left: pageWidth * 0.01),
child: Container(
// alignment: Alignment.centerRight,
width: pageWidth * 0.128,
height: pageWidth * 0.128,
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: CachedNetworkImageProvider(
data[index]['Image'],
)),
borderRadius: BorderRadius.all(
Radius.circular(15)),
// color: Colors.redAccent,
border: Border.all(
color: MyColors.lightGrey,
width: 1,
)),
),
),
Expanded(
child: Row(
children: [
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Container(
width: pageWidth * 0.5,
alignment: Alignment.centerRight,
child: Text(
data[index]['title'],
textAlign: TextAlign.right,
overflow: TextOverflow.ellipsis,
maxLines: 1,
// softWrap: true,
style: TextStyle(
// fontWeight: FontWeight.bold,
fontSize: 14,
),
),
),
],
),
],
),
)
],
),
),
],
),
],
),
),
),
);
}));
}}
can anyone help me please how can I use infinite scrolling to load other pages in my query?
The easiest way is to use a ListView.builder without specifying the itemCount parameter.
Here is the simplest example:
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Infinite List"),
),
body: ListView.builder(
itemBuilder: (context, index) {
return Text("$index");
},
),
);
}
}
Later, you can enhance this by fetching real data. You could show a 'CircularProgressIndicator' in the last item of the list while waiting for the new data.
body: ListView.builder(
itemBuilder: (context, index) {
if (index < data.length) {
// Show your info
return Text("$index");
} else {
getMoreData();
return Center(child: CircularProgressIndicator());
}
},
itemCount: data.length + 1,
),
You can see that we trick the list by adding an index, and calling for more data when displaying that final index.
getMoreData() would include a call to setState() to force a rebuild and to take into account the new data.
Here I've created a flat_list widget which has a similar specification as in React Native. Hope the below works.
FlatList(
+ loading: loading.value,
+ onEndReached: () async {
+ loading.value = true;
+ await Future.delayed(const Duration(seconds: 2));
+ if (context.mounted) {
+ items.value += getMoreData();
+ loading.value = false;
+ }
+ },
data: items.value,
buildItem: (item, index) {
var person = items.value[index];
return ListItemView(person: person);
},
),
I am looking for a way to do widget deletion in the future.
It's easiest to describe the problem through an example (and a MWE).
The user is presented with several AnimatedPositioneds containers, representing a card game.
The PositionedContainer part means that each card can be used for Gin Rummy, Bridge, or, in fact, any abstract numbers card game.
When the user clicks one card, the card slides up (using the Animated part of AnimatedContainer)
and then we'd like the card to be removed from the stack of widgets, i.e. to "disappear" (and not just hide through opacity)
import 'package:flutter/material.dart';
import 'dart:math';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Cards'),
),
body: Center(
child: Container(
alignment: Alignment.center,
child: CardGameWidget(),
decoration: BoxDecoration(
border: Border.all(
color: Colors.blueAccent,
),
),
),
),
),
);
}
}
class CardGameWidget extends StatefulWidget {
#override
CardGameWidgetState createState() => CardGameWidgetState();
}
class CardGameWidgetState extends State<CardGameWidget> {
List<Card> cards = [];
CardGameWidgetState() {
for (var i = 0; i < 5; ++i) {
this.cards.add(Card(
offset: Offset(i * 100.0, 200),
number: Random().nextInt(1 << 16))
);
}
}
Function onTap(int index) => (newOffset) {
setState(() {
cards[index].offset += Offset(0,-100);
});
};
#override
Widget build(BuildContext context) {
List<CardWidget> cardWidgets = [];
for (int i = 0; i < this.cards.length; ++i) {
cardWidgets.add(CardWidget(
onTap: onTap(i),
offset: this.cards[i].offset,
number: this.cards[i].number,
));
}
return Stack(children: cardWidgets);
}
}
class Card {
Card({this.offset, this.number});
Offset offset;
int number;
}
class CardWidget extends StatelessWidget {
CardWidget({
Key key,
this.onTap,
this.offset,
this.number,
});
final Function onTap;
final Offset offset;
final int number;
_handleTap(details) {
onTap(details.globalPosition);
}
#override
Widget build(BuildContext context) {
return AnimatedPositioned(
left: this.offset.dx,
top: this.offset.dy,
width: 100,
height: 100,
duration: Duration(seconds: 1),
child: GestureDetector(
onTapUp: _handleTap,
child: Container(
color: Colors.cyan,
padding: EdgeInsets.all(10),
margin: EdgeInsets.all(10),
child: FittedBox(
clipBehavior: Clip.antiAlias,
alignment: Alignment.centerLeft,
fit: BoxFit.contain,
child: Text(this.number.toString()),
))),
);
}
}
How do I schedule widget deletion as a future event, after the completion of an animation?
You can look into AnimiatedList:
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, brightness: Brightness.dark),
home: SimpleAnimatedList(),
);
}
}
class SimpleAnimatedList extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: SliceAnimatedList(),
);
}
}
class SliceAnimatedList extends StatefulWidget {
#override
_SliceAnimatedListState createState() => _SliceAnimatedListState();
}
class _SliceAnimatedListState extends State<SliceAnimatedList> {
final GlobalKey<AnimatedListState> listKey = GlobalKey<AnimatedListState>();
List<int> _items = [];
int counter = 0;
Widget slideIt(BuildContext context, int index, animation) {
int item = _items[index];
TextStyle textStyle = Theme.of(context).textTheme.headline4;
return SlideTransition(
position: Tween<Offset>(
begin: const Offset(-1, 0),
end: Offset(0, 0),
).animate(animation),
child: SizedBox(
height: 128.0,
child: Card(
color: Colors.primaries[item % Colors.primaries.length],
child: Center(
child: Text('Item $item', style: textStyle),
),
),
),
);
}
#override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Expanded(
child: Container(
height: double.infinity,
child: AnimatedList(
key: listKey,
initialItemCount: _items.length,
itemBuilder: (context, index, animation) {
return slideIt(context, index, animation);
},
),
),
),
Container(
decoration: BoxDecoration(color: Colors.greenAccent),
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FlatButton(
onPressed: () {
setState(() {
listKey.currentState.insertItem(0,
duration: const Duration(milliseconds: 500));
_items = []
..add(counter++)
..addAll(_items);
});
},
child: Text(
"Add item to first",
style: TextStyle(color: Colors.black, fontSize: 20),
),
),
FlatButton(
onPressed: () {
if (_items.length <= 1) return;
listKey.currentState.removeItem(
0, (_, animation) => slideIt(context, 0, animation),
duration: const Duration(milliseconds: 500));
setState(() {
_items.removeAt(0);
});
},
child: Text(
"Remove first item",
style: TextStyle(color: Colors.black, fontSize: 20),
),
)
],
),
),
],
);
}
}
I've been trying to design the layout of my ExpansionTile just like the design below but I couldn't figure out how to change the layout. any suggestion on how to change the border radius, change the background color and also make a gap between each other?.
I tried adding boxDecoration in each container but the style only apply to outside but not on each expansionTile.
import 'package:flutter/material.dart';
class MyReoderWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ReorderItems(topTen: ['j']);
}
}
class DataHolder {
List<String> parentKeys;
Map<String, List<String>> childMap;
DataHolder._privateConstructor();
static final DataHolder _dataHolder = DataHolder._privateConstructor();
static DataHolder get instance => _dataHolder;
factory DataHolder.initialize({#required parentKeys}) {
_dataHolder.parentKeys = parentKeys;
_dataHolder.childMap = {};
for (String key in parentKeys) {
_dataHolder.childMap.putIfAbsent(
}
return _dataHolder;
}
}
class ReorderItems extends StatefulWidget {
final List<String> topTen;
ReorderItems({this.topTen});
#override
_ReorderItemsState createState() => _ReorderItemsState();
}
class _ReorderItemsState extends State<ReorderItems> {
#override
void initState() {
super.initState();
// initialize the children for the Expansion tile
// This initialization can be replaced with any logic like network fetch or something else.
DataHolder.initialize(parentKeys: widget.topTen);
}
#override
Widget build(BuildContext context) {
return PrimaryScrollController(
key: ValueKey(widget.topTen.toString()),
controller: ScrollController(),
child: Container(
decoration: BoxDecoration(),
child: ReorderableListView(
onReorder: onReorder,
children: getListItem(),
),
),
);
}
List<ExpansionTile> getListItem() => DataHolder.instance.parentKeys
.asMap()
.map((index, item) => MapEntry(index, buildTenableListTile(item, index)))
.values
.toList();
ExpansionTile buildTenableListTile(String mapKey, int index) => ExpansionTile(
key: ValueKey(mapKey),
title: Text(mapKey),
leading: Icon(Icons.list),
children: [
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20))
),
key: ValueKey('$mapKey$index'),
height: 200,
child: Container(
padding: EdgeInsets.only(left: 30.0),
child: ReorderList(
parentMapKey: mapKey,
),
),
),
],
);
void onReorder(int oldIndex, int newIndex) {
if (newIndex > oldIndex) {
newIndex -= 1;
}
setState(() {
String game = widget.topTen[oldIndex];
DataHolder.instance.parentKeys.removeAt(oldIndex);
DataHolder.instance.parentKeys.insert(newIndex, game);
});
}
}
class ReorderList extends StatefulWidget {
final String parentMapKey;
ReorderList({this.parentMapKey});
#override
_ReorderListState createState() => _ReorderListState();
}
class _ReorderListState extends State<ReorderList> {
#override
Widget build(BuildContext context) {
return PrimaryScrollController(
controller: ScrollController(),
child: ReorderableListView(
// scrollController: ScrollController(),
onReorder: onReorder,
children: DataHolder.instance.childMap[widget.parentMapKey]
.map(
(String child) => Container(
child: ListTile(
key: ValueKey(child),
leading: Icon(Icons.list),
title: Text(child),
),
),
)
.toList(),
),
);
}
void onReorder(int oldIndex, int newIndex) {
if (newIndex > oldIndex) {
newIndex -= 1;
}
List<String> children = DataHolder.instance.childMap[widget.parentMapKey];
String game = children[oldIndex];
children.removeAt(oldIndex);
children.insert(newIndex, game);
DataHolder.instance.childMap[widget.parentMapKey] = children;
// Need to set state to rebuild the children.
setState(() {});
}
}
You can do it using custom expandable container.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Calendar',
theme: ThemeData(
primarySwatch: Colors.grey,
),
debugShowCheckedModeBanner: false,
home: Material(
child: MyReoderWidget(),
),
);
}
}
class CustomModel {
String title;
bool isExpanded;
List<String> subItems;
CustomModel({this.title, this.subItems, this.isExpanded = false});
}
class MyReoderWidget extends StatefulWidget {
#override
_MyReoderWidgetState createState() => _MyReoderWidgetState();
}
class _MyReoderWidgetState extends State<MyReoderWidget> {
List<CustomModel> listItems;
#override
void initState() {
super.initState();
listItems = List<CustomModel>();
listItems.add(CustomModel(
title: "App Name 1", subItems: ["Card Name 1", "Card Name 2"]));
listItems.add(CustomModel(
title: "App Name 2", subItems: ["Card Name 3", "Card Name 4"]));
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
body: ListView(
children: listItems
.map((model) => new Padding(
padding: EdgeInsets.only(
bottom: 10,
),
child: ExpandableCardContainer(
isExpanded: model.isExpanded,
collapsedChild: createHeaderCard(model),
expandedChild: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.only(
bottom: 10,
),
child: createHeaderCard(model),
)
]..addAll(model.subItems
.map((e) => createChildCard(e))
.toList()),
),
),
))
.toList()),
);
}
Widget createHeaderCard(CustomModel model) {
return Container(
child: Row(
children: <Widget>[
Icon(
Icons.more_vert,
color: Colors.white,
),
Expanded(
child: Text(
model.title,
style: TextStyle(color: Colors.white),
),
),
GestureDetector(
onTap: () {
setState(() {
model.isExpanded = !model.isExpanded;
});
},
child: Icon(
model.isExpanded
? Icons.keyboard_arrow_up
: Icons.keyboard_arrow_down,
color: Colors.white,
),
)
],
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Color(0xFF132435),
),
height: 50,
);
}
Widget createChildCard(String subItems) {
return Container(
margin: EdgeInsets.only(left: 30, bottom: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.more_vert,
color: Colors.white,
),
Expanded(
child: Text(
subItems,
style: TextStyle(color: Colors.white),
),
),
],
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Color(0xFF132435),
),
height: 50,
);
}
}
class ExpandableCardContainer extends StatefulWidget {
final bool isExpanded;
final Widget collapsedChild;
final Widget expandedChild;
const ExpandableCardContainer(
{Key key, this.isExpanded, this.collapsedChild, this.expandedChild})
: super(key: key);
#override
_ExpandableCardContainerState createState() =>
_ExpandableCardContainerState();
}
class _ExpandableCardContainerState extends State<ExpandableCardContainer> {
#override
Widget build(BuildContext context) {
return new AnimatedContainer(
duration: new Duration(milliseconds: 200),
curve: Curves.easeInOut,
child: widget.isExpanded ? widget.expandedChild : widget.collapsedChild,
);
}
}
i tried create a image slider like this image
i tried create this slider with PageView but a have a problem with pageview
and my code :
class SlideMusic extends StatefulWidget{
final Size _size;
final List<String> _listArts;
double itemExtent;
SlideMusic(this._size,this._listArts){
itemExtent = _size.width / 3;
}
#override
SlideMusicState createState() => SlideMusicState();
}
class SlideMusicState extends State<SlideMusic> {
double currentPage = 0;
PageController _pageController = PageController(
viewportFraction: 0.3333,
);
#override
void setState(fn) {
super.setState(fn);
_pageController.addListener((){
currentPage = _pageController.page;
});
}
#override
Widget build(BuildContext context) {
return SizedBox(
width: widget._size.width,
height: widget.itemExtent,
child: Container(
color: Colors.green,
child: NotificationListener<ScrollNotification>(
onNotification: _onNotification,
child: PageView.builder(
controller: _pageController,
physics: BouncingScrollPhysics(),
itemCount: widget._listArts.length,
itemBuilder: (context, index){
return itemArt(widget._listArts[index], index);
},
),
)
)
);
}
bool _onNotification(ScrollNotification notification){
setState(() {
currentPage = _pageController.page;
print(currentPage);
});
}
double itemOffset(int index){
return (index - currentPage ).abs()* widget.itemExtent;
}
Widget itemArt(String image , int index){
Offset offset = Offset.zero;
if(index > currentPage.round())
offset = Offset(-itemOffset(index)/2,0);
else
offset = Offset(itemOffset(index)/2,0);
return Align(
alignment: Alignment.center,
child: Transform.translate(
offset: offset,
child: Container(
color: Colors.lightBlue,
child: LayoutBuilder(
builder: (context,constrat){
return SizedBox(
width: constrat.maxWidth - itemOffset(index)/3.5,
height: constrat.maxHeight - itemOffset(index) /3.5,
child: Center(
child: Image.asset(image)
),
);
},
)
),
)
);
}
}
Check out the Picture slider widget made with carousel_slider.
Don't mind the jankyness of GIF.
Code:
class PictureSlideShow extends StatefulWidget {
#override
_PictureSlideShowState createState() => _PictureSlideShowState();
}
class _PictureSlideShowState extends State<PictureSlideShow> {
#override
Widget build(BuildContext context) {
return Center(
child: CarouselSlider(
height: 200.0,
enlargeCenterPage: true,
items: [1, 2, 3, 4, 5].map((i) {
return Builder(
builder: (BuildContext context) {
return Container(
width: 400,
height: 400,
margin: EdgeInsets.all(0.5),
decoration:
BoxDecoration(color: Colors.lightBlue[100 * (i % 5)]),
child: Center(
child: Text(
'text $i',
style: TextStyle(fontSize: 16.0),
),
),
);
},
);
}).toList(),
),
);
}
}
This is a similiar design to what you wanted.
In this basic sample of how we can use StatesRebuilder, clicking on an item increments the counter value.
Which means:
When I tap on first item, counter is 1, and after clicking on other item counter is incremented to 2, but it should stay to 1 not 2.
The counter value shouldn't inherit from previous item which I tapped on.
my code is not correct:
import 'package:flutter/material.dart';
import 'package:states_rebuilder/states_rebuilder.dart';
class CounterBlocOne extends StatesRebuilder {
Map<String,dynamic> _map = Map<String,dynamic>();
int counter = 0;
increment(tagID) {
counter = _map[tagID];
_map[tagID] = counter++;
rebuildStates([tagID]);
}
}
class RebuildOneExample extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Injector(
models: [() => CounterBlocOne()],
builder: (_, __) => CounterGrid(),
);
}
}
class CounterGrid extends StatelessWidget {
final bloc = Injector.get<CounterBlocOne>();
#override
Widget build(BuildContext context) {
return StateWithMixinBuilder(
mixinWith: MixinWith.automaticKeepAliveClientMixin,
builder: (_, __) => Padding(
padding: EdgeInsets.all(10),
child: Column(
children: <Widget>[
Text("Rebuild The tapped widget"),
Text(
"This page is mixin with automaticKeepAliveClientMixin to not rebuild on sweep in"),
Expanded(
child: GridView.count(
crossAxisCount: 3,
children: <Widget>[
for (var i = 0; i < 12; i++)
StateBuilder(
viewModels: [bloc],
builder: (_, tagID) => GridItem(
count: bloc.counter,
onTap: () => bloc.increment(tagID),
),
)
],
),
),
],
),
),
);
}
}
class GridItem extends StatelessWidget {
final int count;
final Function onTap;
GridItem({this.count, this.onTap});
#override
Widget build(BuildContext context) {
return InkWell(
child: Container(
margin: EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.lightBlue,
border:
Border.all(color: Theme.of(context).primaryColorDark, width: 4),
borderRadius: BorderRadius.circular(6),
),
child: Center(
child: Text(
"$count",
style: TextStyle(
color: Colors.white,
fontSize: 50,
),
),
),
),
onTap: onTap,
);
}
}
Screenshot:
Make 2 changes in your
increment(tagID) {
counter = _map[tagID] ?? 0; // change this
_map[tagID] = ++counter; // and this
rebuildStates([tagID]);
}