Skip to content

Commit

Permalink
feat: Loading information from file. #4
Browse files Browse the repository at this point in the history
  • Loading branch information
LuchoTurtle committed Apr 27, 2023
1 parent b8f2386 commit 9746123
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 33 deletions.
45 changes: 45 additions & 0 deletions assets/menu_items.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
[
{
"id": 1,
"title": "People",
"tiles": [
{
"id": 2,
"title": "Online Now",
"tiles": [
{
"id": 3,
"title": "Family",
"tiles": []
},
{
"id": 4,
"title": "Friends",
"tiles": [
{
"id": 5,
"title": "Sports Team",
"tiles": []
},
{
"id": 6,
"title": "Gamerz",
"tiles": []
}
]
},
{
"id": 7,
"title": "Work",
"tiles": []
}
]
},
{
"id": 8,
"title": "Everyone",
"tiles": []
}
]
}
]
40 changes: 32 additions & 8 deletions lib/menu.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

import 'pages.dart';
import 'tiles.dart';
Expand All @@ -13,6 +16,15 @@ const closeMenuKey = Key("close_key_icon");
class DrawerMenu extends StatelessWidget {
const DrawerMenu({super.key});

Future<List<MenuItemInfo>> _loadMenuItems() async {
final String response = await rootBundle.loadString('assets/menu_items.json');
List<dynamic> data = await json.decode(response);

final List<MenuItemInfo> menuItems = data.map((obj) => MenuItemInfo.fromJson(obj)).toList();

return menuItems;
}

@override
Widget build(BuildContext context) {
return Scaffold(
Expand All @@ -37,14 +49,26 @@ class DrawerMenu extends StatelessWidget {
]),
body: Container(
color: Colors.black,
child: ListView(
key: todoTileKey,
padding: const EdgeInsets.only(top: 32),
children: mockTilesData
.map(
(tile) => MenuItem(tile: tile),
)
.toList())),
child: FutureBuilder<List<MenuItemInfo>>(
future: _loadMenuItems(),
builder: (BuildContext context, AsyncSnapshot<List<MenuItemInfo>> snapshot) {
// If the data is correctly loaded
if (snapshot.hasData) {
return ListView(
key: todoTileKey,
padding: const EdgeInsets.only(top: 32),
children: snapshot.data!
.map(
(tile) => MenuItem(info: tile),
)
.toList());
}

// While it's not loaded (error or waiting)
else {
return const SizedBox.shrink();
}
})),
);
}
}
46 changes: 21 additions & 25 deletions lib/tiles.dart
Original file line number Diff line number Diff line change
@@ -1,19 +1,30 @@
import 'package:flutter/material.dart';

/// Class holding the information of the tile
class BasicTile {
final String title;
final List<BasicTile> tiles;
class MenuItemInfo {
late String title;
late List<MenuItemInfo> tiles;

BasicTile({required this.title, this.tiles = const []});
MenuItemInfo({required this.title, this.tiles = const []});

/// Converts `json` text to BasicTile
MenuItemInfo.fromJson(Map<String, dynamic> json) {
title = json['title'];
if (json['tiles'] != null) {
tiles = [];
json['tiles'].forEach((v) {
tiles.add(MenuItemInfo.fromJson(v));
});
}
}
}

/// Custom tile class that expands if there are child tiles or not.
class MenuItem extends StatefulWidget {
final BasicTile tile;
final MenuItemInfo info;
final double leftPadding;

const MenuItem({super.key, required this.tile, this.leftPadding = 16});
const MenuItem({super.key, required this.info, this.leftPadding = 16});

@override
State<MenuItem> createState() => _MenuItemState();
Expand All @@ -25,10 +36,10 @@ class _MenuItemState extends State<MenuItem> {
@override
Widget build(BuildContext context) {
// If the tile's children is empty, we render the leaf tile
if (widget.tile.tiles.isEmpty) {
if (widget.info.tiles.isEmpty) {
return ListTile(
contentPadding: EdgeInsets.only(left: widget.leftPadding),
title: Text(widget.tile.title,
title: Text(widget.info.title,
style: const TextStyle(
fontSize: 25,
color: Colors.white,
Expand All @@ -39,7 +50,7 @@ class _MenuItemState extends State<MenuItem> {
else {
return ExpansionTile(
tilePadding: EdgeInsets.only(left: widget.leftPadding),
title: Text(widget.tile.title,
title: Text(widget.info.title,
style: const TextStyle(
fontSize: 25,
color: Colors.white,
Expand All @@ -48,26 +59,11 @@ class _MenuItemState extends State<MenuItem> {
_expanded ? Icons.expand_less : Icons.arrow_drop_down,
color: Colors.white,
),
children: widget.tile.tiles.map((tile) => MenuItem(tile: tile, leftPadding: widget.leftPadding + 16)).toList(),
children: widget.info.tiles.map((tile) => MenuItem(info: tile, leftPadding: widget.leftPadding + 16)).toList(),
onExpansionChanged: (bool expanded) {
setState(() => _expanded = expanded);
},
);
}
}
}

/// Mock data.
final mockTilesData = <BasicTile>[
BasicTile(title: "People", tiles: [
BasicTile(title: "Online Now", tiles: [
BasicTile(title: "Family"),
BasicTile(title: "Friends", tiles: [
BasicTile(title: "Sports Team"),
BasicTile(title: "Gamerz"),
]),
BasicTile(title: "Work")
]),
BasicTile(title: "Everyone")
])
];
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ flutter:
# To add assets to your application, add an assets section, like this:
assets:
- assets/images/
- assets/

# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware
Expand Down

0 comments on commit 9746123

Please sign in to comment.