New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Saving the items order #31
Comments
Hi @RoyalCoder88, I am not sure what you exactly want to know. In my I hope that helps. |
Hi thanks, Saving the order of items somehow. |
Sounds like you want to save that to your local storage. You could look for a package like SharedPreferences to save your data. @RoyalCoder88 |
@karvulf I'm using SharedPreferences but can you guide how to achieve saving the order, please? |
Do you have some code snippets for me? Or do you need some guides from scratch? @RoyalCoder88 |
My item code: import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
//import '/../constant/constant.dart';
import 'package:lottie/lottie.dart';
import '../pages/settings/settingGeneral.dart';
import '../widgets/menuGrid.dart';
class GridMenuItem2 extends StatelessWidget {
GridMenuItem2({
required this.color,
required this.animId,
required this.category,
required this.activeAnim,
required this.menuId,
required this.newIndex,
required this.oldIndex,
Key? key,
}) : super(key: key);
final String menuId;
final Color color;
final String animId;
final String category;
final bool activeAnim;
int newIndex = 0;
int oldIndex = 0;
int get oindex => oldIndex;
set oindex(int value) {
oldIndex = value;
}
int get nindex => newIndex;
set nindex(int value) {
newIndex = value;
}
@override
Widget build(BuildContext context) {
return Card(
key: ValueKey(animId),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(25.0)),
shadowColor: Colors.black54,
//color: culoare,
child: InkWell(
onTap: () {
print(menuId);
Navigator.push(
context,
CupertinoPageRoute(
builder: (context) => const SettingsScreen(),
));
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
//verticalDirection: VerticalDirection.down,
children: <Widget>[
Lottie.asset('assets/lotties/$category/$animId.json',
animate: activeAnim, width: 70, height: 70, fit: BoxFit.fill),
const SizedBox(height: 2.0),
Text(animId.toUpperCase(),
style: const TextStyle(
fontSize: 10.0, fontWeight: FontWeight.bold))
],
),
),
);
}
} And for the grid I'm using your example, I tried a lot for saving the items ordered on reorder and retrieve them on initState() but so far not so successfully, I think this will be an amazing feature for your package and much appreciated by devs. |
How did you use my example, can you add this code also? @RoyalCoder88 |
Hi @karvulf This is my code implementation: import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:flutter_reorderable_grid_view/entities/order_update_entity.dart';
import 'package:flutter_reorderable_grid_view/widgets/reorderable_builder.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../widgets/app_placeholder.dart';
import '../../widgets/progress.dart';
import '../../constant/constant.dart';
import '../../models/menuIGridtem.dart';
import '../../models/user.dart';
import '../../widgets/app_user_info.dart';
import '../../widgets/headerMenuGeneral.dart';
import '../home.dart';
import 'package:sticky_headers/sticky_headers.dart';
class MainMenuUni extends StatefulWidget {
//final String? currentUserId;
//const MainMenuUni({Key? key, this.currentUserId}) : super(key: key);
@override
_MainMenuUniState createState() {
return _MainMenuUniState();
}
}
class _MainMenuUniState extends State<MainMenuUni> {
//SharedPreferences _preferences = SharedPreferences.getInstance();
final _prefs = SharedPreferences.getInstance();
late List<String> _menuItemsSavedGrid = [];
final _scaffoldKey = GlobalKey<ScaffoldState>();
late GloabalUser user;
bool isLoading = false;
final lockedIndices = <int>[];
List<GridMenuItem> menuGridList = [];
List<SavedMenuItemGrid> listSavedGridMenu = [];
final ReorderableType reorderableType = ReorderableType.gridView;
@override
void initState() {
getUser();
initGrid();
super.initState();
}
// @override
// void dispose() {
// super.dispose();
// }
initGrid() async {
_generateMenuItems();
getGridData();
if (_menuItemsSavedGrid.isNotEmpty) {
// for (int i = 0; i < _menuItemsSavedGrid!.length; i++) {
// insertData(i);
// }
reorderlistview();
}
}
getGridData() async {
SharedPreferences _prefs = await SharedPreferences.getInstance();
_menuItemsSavedGrid = _prefs.getStringList('menuGridItems') ?? ['menuGol'];
print('MENU GRID LIST: $_menuItemsSavedGrid');
}
setGridData() async {
SharedPreferences _prefs = await SharedPreferences.getInstance();
_prefs.setStringList('menuGridItems', <String>[menuGridList.toString()]);
}
//REORDER LOGIC**************************************************************
reorderlistview() {
for (int i = 0; i < menuGridList.length; i++) {
print(menuGridList[i].menuID);
setState(() {});
}
}
void _generateMenuItems() {
menuGridList.addAll(
[
GridMenuItem(
menuID: 'Menu 1',
colorWidget: Colors.orange,
idAnim: 'angry',
category: 'uni',
animActiva: true,
oldIndex: 0,
newIndex: 0,
key: ValueKey('angry'),
),
GridMenuItem(
menuID: 'Menu 1',
colorWidget: Colors.orange,
idAnim: 'camp-fire',
category: 'uni',
animActiva: true,
oldIndex: 1,
newIndex: 1,
key: ValueKey('camp'),
),
GridMenuItem(
menuID: 'Menu 1',
colorWidget: Colors.orange,
idAnim: 'like',
category: 'uni',
animActiva: true,
oldIndex: 2,
newIndex: 2,
key: ValueKey('like'),
),
GridMenuItem(
menuID: 'Menu 1',
colorWidget: Colors.orange,
idAnim: 'lol',
category: 'uni',
animActiva: true,
oldIndex: 3,
newIndex: 3,
key: ValueKey('lol'),
),
GridMenuItem(
menuID: 'Menu 1',
colorWidget: Colors.orange,
idAnim: 'love',
category: 'uni',
animActiva: true,
oldIndex: 4,
newIndex: 4,
),
GridMenuItem(
menuID: 'Menu 1',
colorWidget: Colors.orange,
idAnim: 'sad',
category: 'uni',
animActiva: true,
oldIndex: 5,
newIndex: 5,
key: ValueKey('sad'),
),
GridMenuItem(
menuID: 'Menu 1',
colorWidget: Colors.orange,
idAnim: 'trend',
category: 'uni',
animActiva: true,
oldIndex: 6,
newIndex: 6,
key: ValueKey('trend'),
),
GridMenuItem(
menuID: 'Menu 1',
colorWidget: Colors.orange,
idAnim: 'uni_loading',
category: 'uni',
animActiva: true,
oldIndex: 7,
newIndex: 7,
key: ValueKey('uni_loading'),
),
GridMenuItem(
menuID: 'Menu 1',
colorWidget: Colors.orange,
idAnim: 'wow',
category: 'uni',
animActiva: true,
oldIndex: 8,
newIndex: 8,
key: ValueKey('wow'),
),
GridMenuItem(
menuID: 'Menu 1',
colorWidget: Colors.orange,
idAnim: 'upIn',
category: 'uni',
animActiva: true,
oldIndex: 9,
newIndex: 9,
key: ValueKey('upIn'),
),
GridMenuItem(
menuID: 'Menu 1',
colorWidget: Colors.orange,
idAnim: 'upIn2',
category: 'uni',
animActiva: true,
oldIndex: 10,
newIndex: 10,
key: ValueKey('upIn2'),
),
GridMenuItem(
menuID: 'Menu 1',
colorWidget: Colors.orange,
idAnim: 'angry',
category: 'uni',
animActiva: true,
oldIndex: 11,
newIndex: 11,
key: ValueKey('angry22'),
),
],
);
}
///On navigation
// void _onNavigate(String route) {
// Navigator.pushNamed(context, route);
// }
@override
Widget build(BuildContext context) {
return AnimatedTheme(
duration: const Duration(milliseconds: 100),
data: Theme.of(context),
child: Scaffold(
//backgroundColor: Colors.white,
appBar: headerMenuGeneral(context,
isAppTitle: true,
iscenterTitle: false,
removeBackButton: false,
showOnlineToggle: true),
body: isLoading
? circularProgress()
: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 16),
child: Column(
children: <Widget>[
StickyHeader(
content: _meniuSecundar(),
header: Container(
padding: const EdgeInsets.all(1),
//margin: const EdgeInsets.symmetric(horizontal: 2),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4),
color: Theme.of(context).cardColor,
boxShadow: [
BoxShadow(
color:
Theme.of(context).dividerColor.withOpacity(
.25,
),
spreadRadius: 4,
blurRadius: 4,
offset: const Offset(
0,
2,
), // changes position of shadow
),
],
),
//child: AppUserInfo(
// user: user,
// type: AppUserType.information,
// onPressed: () {},
// ),
),
),
const SizedBox(height: 30),
],
),
),
),
),
);
}
_handleReorder(List<OrderUpdateEntity> onReorderList) async {
for (final reorder in onReorderList) {
final child = menuGridList.removeAt(reorder.oldIndex);
menuGridList.insert(reorder.newIndex, child);
// final childNew = _menuItemsSavedGrid.removeAt(reorder.oldIndex);
// _menuItemsSavedGrid.insert(reorder.newIndex, 'child');
print(reorder.oldIndex.toString() +
" MENU INDX " +
reorder.newIndex.toString());
}
setGridData();
//setState(() {});
}
Widget _meniuSecundar() {
return Column(
children: [
const SizedBox(height: 20),
//_statsUser(),
const SizedBox(height: 16),
Column(
children: <Widget>[
Container(
height: 700,
color: Colors.white,
child: _getReorderableWidget(),
),
],
),
],
);
}
Widget _getReorderableWidget() {
final generatedChildren = List<Widget>.generate(
menuGridList.length,
(index) => GridMenuItem(
menuID: menuGridList[index].menuID,
colorWidget: Colors.orange,
idAnim: menuGridList[index].idAnim,
category: menuGridList[index].category,
animActiva: menuGridList[index].animActiva,
oldIndex: menuGridList[index].oldIndex,
newIndex: menuGridList[index].newIndex,
key: menuGridList[index].key,
),
);
switch (reorderableType) {
case ReorderableType.gridView:
return ReorderableBuilder(
children: generatedChildren,
onReorder: _handleReorder,
lockedIndices: lockedIndices,
builder: (children, scrollController) {
return GridView(
controller: scrollController,
children: children,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
mainAxisSpacing: 4,
crossAxisSpacing: 8,
),
);
},
);
case ReorderableType.gridViewCount:
return ReorderableBuilder(
children: generatedChildren,
onReorder: _handleReorder,
lockedIndices: lockedIndices,
dragChildBoxDecoration: BoxDecoration(
color: Colors.orange.withOpacity(0.5),
borderRadius: BorderRadius.circular(25.0),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset: const Offset(0, 3), // changes position of shadow
),
],
//border: BoxBorder.
//shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(25.0)),
),
builder: (children, scrollController) {
return GridView.count(
scrollDirection: Axis.vertical,
controller: scrollController,
key: const Key('count'),
children: children,
crossAxisCount: 3,
);
},
);
case ReorderableType.gridViewExtent:
return ReorderableBuilder(
children: generatedChildren,
onReorder: _handleReorder,
lockedIndices: lockedIndices,
builder: (children, scrollController) {
return GridView.extent(
controller: scrollController,
key: const Key('extent'),
children: children,
maxCrossAxisExtent: 200,
);
},
);
case ReorderableType.gridViewBuilder:
return ReorderableBuilder(
children: generatedChildren,
onReorder: _handleReorder,
lockedIndices: lockedIndices,
builder: (children, scrollController) {
return GridView.builder(
key: const Key('builder'),
controller: scrollController,
itemCount: children.length,
itemBuilder: (context, index) {
return children[index];
},
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
mainAxisSpacing: 4,
crossAxisSpacing: 8,
),
);
},
);
}
}
}
class SavedMenuItemGrid {
String itemId = "";
int itemIndex = 0;
} Thanks in advance! |
Ok I see, there are some points, that are a bit unusual, Im coming back with an example, how you could write this code, so that it works for you @RoyalCoder88 |
Thanks a lot @karvulf |
Well your example is really difficult to fix like that is, so I created an example that could be similar to your code and I hope it helps. There are also other things, that should be changed, but I think, this is enough for the beginning. You should try to work a little bit more with flutter to get in touch with the other things. You could also think about a state management like Also you should separate your logic from your widget e. g. loading data from storage. I am closing this issue, because it was not related to the package. @RoyalCoder88 import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_reorderable_grid_view/entities/order_update_entity.dart';
import 'package:flutter_reorderable_grid_view/widgets/reorderable_builder.dart';
import 'package:shared_preferences/shared_preferences.dart';
class MainMenuUni extends StatefulWidget {
const MainMenuUni({Key? key}) : super(key: key);
@override
_MainMenuUniState createState() => _MainMenuUniState();
}
class _MainMenuUniState extends State<MainMenuUni> {
var menuGridListEntities = List<GridMenuItemEntity>.generate(
12,
(index) => GridMenuItemEntity(
id: 'menu_item_$index',
),
);
bool isLoading = true;
@override
void initState() {
super.initState();
getGridData();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('MainMenuUni')),
body: isLoading
? const CircularProgressIndicator()
: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 16),
child: Column(
children: <Widget>[
Container(
height: 700,
color: Colors.white,
child: _getReorderableWidget(),
),
],
),
),
),
);
}
Widget _getReorderableWidget() {
final generatedChildren = List<Widget>.generate(
menuGridListEntities.length,
(index) => ColoredBox(
key: Key(menuGridListEntities[index].id.toString()),
color: Colors.orange,
child: Text(
menuGridListEntities[index].id.toString(),
),
),
);
return ReorderableBuilder(
children: generatedChildren,
onReorder: _handleReorder,
builder: (children, scrollController) {
return GridView(
controller: scrollController,
children: children,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
mainAxisSpacing: 4,
crossAxisSpacing: 8,
),
);
},
);
}
void _handleReorder(List<OrderUpdateEntity> onReorderList) {
for (final reorder in onReorderList) {
final child = menuGridListEntities.removeAt(reorder.oldIndex);
menuGridListEntities.insert(reorder.newIndex, child);
}
setGridData();
}
Future<void> getGridData() async {
SharedPreferences _prefs = await SharedPreferences.getInstance();
final jsonString = _prefs.getStringList('menuGridItems');
if (jsonString != null) {
menuGridListEntities = jsonString
.map((e) => GridMenuItemEntity.fromJson(
jsonDecode(e),
))
.toList();
}
setState(() {
isLoading = false;
});
}
Future<void> setGridData() async {
final jsonList = menuGridListEntities
.map((e) => jsonEncode(
e.toJson(),
))
.toList();
SharedPreferences _prefs = await SharedPreferences.getInstance();
_prefs.setStringList('menuGridItems', jsonList);
}
}
class GridMenuItemEntity {
final String id;
const GridMenuItemEntity({
required this.id,
});
factory GridMenuItemEntity.fromJson(Map<String, dynamic> json) =>
GridMenuItemEntity(
id: json['id'],
);
Map<String, dynamic> toJson() => {'id': id};
} |
@karvulf Thanks a lot for your example I managed to remake my entire logic & code, thanks for your feature suggestion and thanks your support is amazing! |
Glad to hear that and no problem! |
Hi Karvulf,
Can you please add the feature on how to save the order of times, so for the next time the user gets the list to have the order he saved?
Or can you guide me how to achieve this, please?
Thanks in advance!
The text was updated successfully, but these errors were encountered: