I have a list of some categories and recipes (food recipes app). So, I have two questions:
Why I see empty space, when open the Category? I think it gives SizedBox(), but I can't write null at this place, because of crash.
Did I make the correct condition for checking a recipe for a category?
Recipes Tab
class RecipesTab extends StatefulWidget {
@override
_RecipesTabState createState() => _RecipesTabState();
}
class _RecipesTabState extends State<RecipesTab> {
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
initialIndex: 1,
child: Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
title: Text('Книга рецептов'),
bottom: TabBar(
isScrollable: true,
indicatorPadding: EdgeInsets.all(10),
indicatorColor: Color(0xFF0FA3B1),
labelColor: Color(0xFF0FA3B1),
tabs: [
Tab(text: 'Избранное'),
Tab(text: 'Категории'),
],
),
),
body: Padding(
padding: const EdgeInsets.only(top: 5.0),
child: TabBarView(
children: [
Favorite(),
Categories(),
],
),
),
),
);
}
}
Categories
class Categories extends StatefulWidget {
@override
_CategoriesState createState() => _CategoriesState();
}
class _CategoriesState extends State<Categories> {
Future<List<Category>> _getCategories() async {
var data = await http.get(
"https://ibragimov.xyz:7000/categories/?format=json",
headers: {'Content-Type': 'application/json; charset=utf-8'},
);
var jsonData = json.decode(utf8.decode(data.bodyBytes));
List<Category> categories = [];
for (var i in jsonData) {
Category category = Category(i['id'], i['name']);
categories.add(category);
}
return categories;
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _getCategories(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.data == null) {
return Container(
child: Padding(
padding: const EdgeInsets.all(50.0),
child: Center(
child: CircularProgressIndicator(),
),
),
);
} else {
return Container(
child: ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int id) {
return Card(
elevation: 0,
margin: EdgeInsets.symmetric(horizontal: 10, vertical: 5),
child: ListTile(
title: Text(snapshot.data[id].name),
trailing: Icon(Icons.arrow_forward_ios_rounded),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
Recipes(snapshot.data[id])));
},
),
);
},
),
);
}
},
);
}
}
class Category {
final int id;
final String name;
Category(this.id, this.name);
}
Recipes
class Recipes extends StatefulWidget {
final Category category;
Recipes(this.category);
@override
_RecipesState createState() => _RecipesState();
}
class _RecipesState extends State<Recipes> {
Future<List<Recipe>> _getRecipes() async {
var data = await http.get("https://ibragimov.xyz:7000/recipes/?format=json",
headers: {'Content-Type': 'application/json; charset=utf-8'});
var jsonData = json.decode(utf8.decode(data.bodyBytes));
List<Recipe> recipes = [];
for (var i in jsonData) {
Recipe recipe =
Recipe(i['id'], i['name'], i['cost'], i["category"], i["photo"]);
recipes.add(recipe);
}
return recipes;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.category.name),
),
body: FutureBuilder(
future: _getRecipes(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.data == null) {
return Container(
child: Padding(
padding: const EdgeInsets.all(50.0),
child: Center(
child: CircularProgressIndicator(),
),
),
);
} else {
return Container(
child: GridView.builder(
shrinkWrap: true,
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int id) {
return snapshot.data[id].category == widget.category.name
? Card(
elevation: 0,
margin:
EdgeInsets.symmetric(horizontal: 10, vertical: 5),
child: GridTile(
child: Image.network(
'https://2recepta.com/recept/omlet-s-pomidorami/omlet-s-pomidorami.jpg',
fit: BoxFit.cover,
height: 100,
width: 100,
),
footer: Text(snapshot.data[id].name),
header: Text('data'),
),
)
: SizedBox.shrink();
},
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 250,
mainAxisSpacing: 4.0,
crossAxisSpacing: 4.0,
),
),
);
}
},
),
);
}
}
class Recipe {
final int id;
final String name;
final int cost;
final String category;
final String photo;
Recipe(this.id, this.name, this.cost, this.category, this.photo);
}
Screenshots: