0

i'm creating a flutter app for restaurant menu and i have multiple JSON files that contains data for ex. drinks, food, and sweats. my question is how to create one flutter page only so that if clicked on dinks in home page it will show drinks.JSON data in the second screen and etc...becasue now i have multiple dart pages for each JSON data. is there a way to pass the clicked page's id and view JSON file depending on it in one dart page? P.S: all JSON files saved in same place assets/blbla.JSON

//Home Page

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
import 'package:hexcolor/hexcolor.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:localize_and_translate/localize_and_translate.dart';
import 'package:menu_app/coldDrinks.dart';
import 'package:menu_app/hotDrinks.dart';

void main() => runApp(Drinks());

// class Drinks extends StatelessWidget {
//   // This widget is the root of your application.
//   @override
//   Widget build(BuildContext context) {
//     return MaterialApp(
//       debugShowCheckedModeBanner: false,
//       home: Drinks(),
//       title: 'Flutter Demo',
//       theme: ThemeData(),
//     );
//   }
// }

var bannerItems = ["", " ", "", ""];
var bannerImage = [
  "assets/images/p-4.jfif",
  "assets/images/p-1.jfif",
  "assets/images/p-2.jfif",
  "assets/images/p-3.jfif"
];

class Drinks extends StatefulWidget {
  @override
  _DrinksState createState() => _DrinksState();
}

class _DrinksState extends State<Drinks> {
  @override
  @override
  Widget build(BuildContext context) {
    debugShowCheckedModeBanner:
    false;
    var screenHeight = MediaQuery.of(context).size.height;
    var screenWidth = MediaQuery.of(context).size.width;

    return Scaffold(
      appBar: AppBar(
        backgroundColor: HexColor("#242424"),
        leading: IconButton(
          icon: Icon(Icons.arrow_back_ios),
          iconSize: 20.0,
          onPressed: () {
            Navigator.pop(context);
          },
        ),
        title: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Image.asset(
              "assets/images/logo.png",
              fit: BoxFit.contain,
              height: 40,
            ),
          ],
        ),
      ),
      body: Container(
          decoration: BoxDecoration(
            image: DecorationImage(
              image: AssetImage("assets/images/dark.jpg"),
              fit: BoxFit.cover,
            ),
          ),
          height: screenHeight,
          width: screenWidth,
          child: SafeArea(
              child: SingleChildScrollView(
                  child: Column(
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: <Widget>[
                SizedBox(height: 30),
                Container(
                    decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(15.0),
                      image: DecorationImage(
                        image: AssetImage("assets/images/hot.jfif"),
                        fit: BoxFit.cover,
                        colorFilter: ColorFilter.mode(
                            Colors.black.withOpacity(0.2), BlendMode.darken),
                      ),
                    ),
                    width: 300,
                    height: 180,
                    padding: new EdgeInsets.all(10.0),
                    child: Center(
                        child: GestureDetector(
                      onTap: () {
                        Navigator.push(
                          context,
                          MaterialPageRoute(builder: (context) => HotDrinks()), // how to pass id here and view JSON in second screen depending on clicked page?
                        );
                      },
                      child: Text(
                        translator.translate(' cold drinks'),
                        style: GoogleFonts.elMessiri(
                            textStyle: TextStyle(
                                fontWeight: FontWeight.bold,
                                fontSize: 30.0,
                                color: Colors.white70)),
                      ),
                    ))),
                           Container(
                    decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(15.0),
                      image: DecorationImage(
                        image: AssetImage("assets/images/cold.jfif"),
                        fit: BoxFit.cover,
                        colorFilter: ColorFilter.mode(
                            Colors.black.withOpacity(0.2), BlendMode.darken),
                      ),
                    ),
                    width: 300,
                    height: 180,
                    padding: new EdgeInsets.all(10.0),
                    child: Center(
                        child: GestureDetector(
                      onTap: () {
                        Navigator.push(
                          context,
                          MaterialPageRoute(builder: (context) => coldDrinks()), 
                        );
                      },
                      child: Text(
                        translator.translate(' hot drinks'),
                        style: GoogleFonts.elMessiri(
                            textStyle: TextStyle(
                                fontWeight: FontWeight.bold,
                                fontSize: 30.0,
                                color: Colors.white70)),
                      ),
                    ))),
                SizedBox(
                  height: 10,
                ),
        
                ClipRect(
                  child: Container(
                    color: HexColor("#242424"),
                    height: 30,
                    width: (MediaQuery.of(context).size.width),
                    child: Padding(
                      padding: const EdgeInsets.fromLTRB(10, 5, 10, 5),
                      child: Text(
                        "©2021 All Rights Reserved. Designed and Powered by SWC.",
                        textAlign: TextAlign.center,
                        style: TextStyle(color: Colors.white, fontSize: 12),
                      ),
                    ),
                  ),
                ),
              ])))),
      floatingActionButton: FloatingActionButton(
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => About()),
            );
          },
          backgroundColor: Colors.black,
          child: Icon(
            MdiIcons.information,
            color: Colors.white,
          )),
    );
  }
}

Second page that views data:

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:hexcolor/hexcolor.dart';
import 'package:localize_and_translate/localize_and_translate.dart';
import 'package:menu_app/Drinks.dart';

void main() => runApp(HotDrinks());


class HotDrinks extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var screenHeight = MediaQuery.of(context).size.height;
    var screenWidth = MediaQuery.of(context).size.width;

    Future<List<Widget>> createList() async {
      List<Widget> items = <Widget>[];
      String dataString = await rootBundle
          .loadString(translator.translate("assets/hotDrinks.json")); //view JSON file depending on clicked page
      List<dynamic> dataJSON = jsonDecode(dataString);

      dataJSON.forEach((object) {
        String finalString = "";
        List<dynamic> dataList = object["placeItems"];
        dataList.forEach((item) {
          finalString = finalString + item + " | ";
        });

        items.add(Padding(
          padding: EdgeInsets.all(2.0),
          child: Container(
            decoration: BoxDecoration(
                color: Color.fromRGBO(255, 255, 255, 0.7),
                borderRadius: BorderRadius.all(Radius.circular(10.0)),
                boxShadow: [
                  BoxShadow(
                      color: Colors.black12,
                      spreadRadius: 2.0,
                      blurRadius: 5.0),
                ]),
            margin: EdgeInsets.all(5.0),
            child: Column(
              mainAxisSize: MainAxisSize.max,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                ClipRRect(
                  // borderRadius: BorderRadius.only(
                  //     topLeft: Radius.circular(10.0),
                  //     bottomLeft: Radius.circular(10.0)),
                  child: Image.asset(
                    object["placeImage"],
                    fit: BoxFit.cover,
                    width: 280,
                    height: 180,
                  ),
                ),
                SizedBox(
                  width: 250,
                  child: Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        Text(
                          translator.translate(object["placeName"]),
                          style: GoogleFonts.elMessiri(
                              textStyle: TextStyle(
                                  fontSize: 15.0, color: Colors.black54)),
                        ),
                        // Padding(
                        //   padding: const EdgeInsets.only(top: 2.0, bottom: 2.0),
                        //   child: Text(
                        //     finalString,
                        //     overflow: TextOverflow.ellipsis,
                        //     style: TextStyle(
                        //       fontSize: 12.0,
                        //       color: Colors.black54,
                        //     ),
                        //     maxLines: 1,
                        //   ),
                        // ),
                        Text(
                          translator.translate(" ${object["minOrder"]} IQD"),
                          style:
                              TextStyle(fontSize: 12.0, color: Colors.black54),
                        )
                      ],
                    ),
                  ),
                )
              ],
            ),
          ),
        ));
      });

      return items;
    }

    return Scaffold(
      appBar: AppBar(
        backgroundColor: HexColor("#242424"),
        leading: IconButton(
          icon: Icon(Icons.arrow_back_ios),
          iconSize: 20.0,
          onPressed: () {
            Navigator.pop(context);
          },
        ),
        title: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Image.asset(
              "assets/images/logo.png",
              fit: BoxFit.contain,
              height: 40,
            ),
          ],
        ),
      ),
      body: SafeArea(
          child: SingleChildScrollView(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisSize: MainAxisSize.min, // set min
          children: <Widget>[
            Container(
              decoration: BoxDecoration(
                image: DecorationImage(
                  image: AssetImage("assets/images/backg.png"),
                  fit: BoxFit.cover,
                ),
              ),
              height: 3000,
              width: screenWidth,
              child: FutureBuilder<List<Widget>>(
                  initialData: [Text("")],
                  future: createList(),
                  builder: (context, snapshot) {
                    if (snapshot.connectionState == ConnectionState.waiting)
                      return Text("Loading");

                    if (snapshot.hasError) {
                      return Text("Error ${snapshot.error}");
                    }
                    if (snapshot.hasData) {
                      return Padding(
                          padding: EdgeInsets.all(8.0),
                          child: GridView.count(
                            childAspectRatio: 1, // items' width/height
                            crossAxisCount: 2,
                            shrinkWrap: true,
                            physics: NeverScrollableScrollPhysics(),
                            children: [
                              // ignore: sdk_version_ui_as_code
                              ...?snapshot.data,
                            ],
                          ));
                    } else {
                      return CircularProgressIndicator();
                    }
                  }),
            )
          ],
        ),
      )),
      floatingActionButton: FloatingActionButton(
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => About()),
            );
          },
          backgroundColor: Colors.black,
          child: Icon(
            MdiIcons.information,
            color: Colors.white,
          )),
    );
  }
}
sara97
  • 209
  • 2
  • 11

1 Answers1

1

You can pass the pageId as a required parameter to the widget.

   import 'dart:convert';
    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
    import 'package:google_fonts/google_fonts.dart';
    import 'package:hexcolor/hexcolor.dart';
    import 'package:localize_and_translate/localize_and_translate.dart';
    import 'package:menu_app/Drinks.dart';

    class FoodDetailsPage extends StatefulWidget {
      final String pageId;
      //The string of each meal will be passed when calling this page.
      FoodDetailsPage({@required this.pageId});

  @override
  _FoodDetailsPageState createState() => _FoodDetailsPageState();
}

class _FoodDetailsPageState extends State<FoodDetailsPage> {
      Future<List<Widget>> myCreateList;
      @override
      void initState() {
        super.initState();
        myCreateList = createList();
        //THIS IS NECESSARY TO AVOID THE FUTUREBUILDER FROM FIRING EVERYTIME THE PAGE REBUILDS.
        // You can check more at
        // https://stackoverflow.com/questions/57793479/flutter-futurebuilder-gets-constantly-called
      }
      Future<List<Widget>> createList() async {
          List<Widget> items = <Widget>[];
          String dataString = await rootBundle
              .loadString(translator.translate("assets/${widget.pageId}.json")); //view JSON file depending on pageId
          List<dynamic> dataJSON = jsonDecode(dataString);

          dataJSON.forEach((object) {
            String finalString = "";
            List<dynamic> dataList = object["placeItems"];
            dataList.forEach((item) {
              finalString = finalString + item + " | ";
            });

            items.add(Padding(
              padding: EdgeInsets.all(2.0),
              child: Container(
                decoration: BoxDecoration(
                    color: Color.fromRGBO(255, 255, 255, 0.7),
                    borderRadius: BorderRadius.all(Radius.circular(10.0)),
                    boxShadow: [
                      BoxShadow(
                          color: Colors.black12,
                          spreadRadius: 2.0,
                          blurRadius: 5.0),
                    ]),
                margin: EdgeInsets.all(5.0),
                child: Column(
                  mainAxisSize: MainAxisSize.max,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    ClipRRect(
                      // borderRadius: BorderRadius.only(
                      //     topLeft: Radius.circular(10.0),
                      //     bottomLeft: Radius.circular(10.0)),
                      child: Image.asset(
                        object["placeImage"],
                        fit: BoxFit.cover,
                        width: 280,
                        height: 180,
                      ),
                    ),
                    SizedBox(
                      width: 250,
                      child: Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: <Widget>[
                            Text(
                              translator.translate(object["placeName"]),
                              style: GoogleFonts.elMessiri(
                                  textStyle: TextStyle(
                                      fontSize: 15.0, color: Colors.black54)),
                            ),
                            // Padding(
                            //   padding: const EdgeInsets.only(top: 2.0, bottom: 2.0),
                            //   child: Text(
                            //     finalString,
                            //     overflow: TextOverflow.ellipsis,
                            //     style: TextStyle(
                            //       fontSize: 12.0,
                            //       color: Colors.black54,
                            //     ),
                            //     maxLines: 1,
                            //   ),
                            // ),
                            Text(
                              translator.translate(" ${object["minOrder"]} IQD"),
                              style:
                                  TextStyle(fontSize: 12.0, color: Colors.black54),
                            )
                          ],
                        ),
                      ),
                    )
                  ],
                ),
              ),
            ));
          });

          return items;
        }

      Widget build(BuildContext context) {
        var screenHeight = MediaQuery.of(context).size.height;
        var screenWidth = MediaQuery.of(context).size.width;

        

        return Scaffold(
          appBar: AppBar(
            backgroundColor: HexColor("#242424"),
            leading: IconButton(
              icon: Icon(Icons.arrow_back_ios),
              iconSize: 20.0,
              onPressed: () {
                Navigator.pop(context);
              },
            ),
            title: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Image.asset(
                  "assets/images/logo.png",
                  fit: BoxFit.contain,
                  height: 40,
                ),
              ],
            ),
          ),
          body: SafeArea(
              child: SingleChildScrollView(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.center,
              mainAxisSize: MainAxisSize.min, // set min
              children: <Widget>[
                Container(
                  decoration: BoxDecoration(
                    image: DecorationImage(
                      image: AssetImage("assets/images/backg.png"),
                      fit: BoxFit.cover,
                    ),
                  ),
                  height: 3000,
                  width: screenWidth,
                  child: FutureBuilder<List<Widget>>(
                      initialData: [Text("")],
                      future: myCreateList,
                      builder: (context, snapshot) {
                        if (snapshot.connectionState == ConnectionState.waiting)
                          return Text("Loading");

                        if (snapshot.hasError) {
                          return Text("Error ${snapshot.error}");
                        }
                        if (snapshot.hasData) {
                          return Padding(
                              padding: EdgeInsets.all(8.0),
                              child: GridView.count(
                                childAspectRatio: 1, // items' width/height
                                crossAxisCount: 2,
                                shrinkWrap: true,
                                physics: NeverScrollableScrollPhysics(),
                                children: [
                                  // ignore: sdk_version_ui_as_code
                                  ...?snapshot.data,
                                ],
                              ));
                        } else {
                          return CircularProgressIndicator();
                        }
                      }),
                )
              ],
            ),
          )),
          floatingActionButton: FloatingActionButton(
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => About()),
                );
              },
              backgroundColor: Colors.black,
              child: Icon(
                MdiIcons.information,
                color: Colors.white,
              )),
        );
      }
}

Then the homepage would look like this.

//Home Page

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
import 'package:hexcolor/hexcolor.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:localize_and_translate/localize_and_translate.dart';
import 'package:menu_app/coldDrinks.dart';
import 'package:menu_app/hotDrinks.dart';

void main() => runApp(Drinks());

// class Drinks extends StatelessWidget {
//   // This widget is the root of your application.
//   @override
//   Widget build(BuildContext context) {
//     return MaterialApp(
//       debugShowCheckedModeBanner: false,
//       home: Drinks(),
//       title: 'Flutter Demo',
//       theme: ThemeData(),
//     );
//   }
// }

var bannerItems = ["", " ", "", ""];
var bannerImage = [
  "assets/images/p-4.jfif",
  "assets/images/p-1.jfif",
  "assets/images/p-2.jfif",
  "assets/images/p-3.jfif"
];

class Drinks extends StatefulWidget {
  @override
  _DrinksState createState() => _DrinksState();
}

class _DrinksState extends State<Drinks> {
  @override
  @override
  Widget build(BuildContext context) {
    debugShowCheckedModeBanner:
    false;
    var screenHeight = MediaQuery.of(context).size.height;
    var screenWidth = MediaQuery.of(context).size.width;

    return Scaffold(
      appBar: AppBar(
        backgroundColor: HexColor("#242424"),
        leading: IconButton(
          icon: Icon(Icons.arrow_back_ios),
          iconSize: 20.0,
          onPressed: () {
            Navigator.pop(context);
          },
        ),
        title: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Image.asset(
              "assets/images/logo.png",
              fit: BoxFit.contain,
              height: 40,
            ),
          ],
        ),
      ),
      body: Container(
          decoration: BoxDecoration(
            image: DecorationImage(
              image: AssetImage("assets/images/dark.jpg"),
              fit: BoxFit.cover,
            ),
          ),
          height: screenHeight,
          width: screenWidth,
          child: SafeArea(
              child: SingleChildScrollView(
                  child: Column(
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: <Widget>[
                SizedBox(height: 30),
                Container(
                    decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(15.0),
                      image: DecorationImage(
                        image: AssetImage("assets/images/hot.jfif"),
                        fit: BoxFit.cover,
                        colorFilter: ColorFilter.mode(
                            Colors.black.withOpacity(0.2), BlendMode.darken),
                      ),
                    ),
                    width: 300,
                    height: 180,
                    padding: new EdgeInsets.all(10.0),
                    child: Center(
                        child: GestureDetector(
                      onTap: () {
                        Navigator.push(
                          context,
                          MaterialPageRoute(builder: (context) => FoodDetailsPage(pageId: "hotDrinks",)), // pass id here and view JSON in second screen depending on clicked page
                        );
                      },
                      child: Text(
                        translator.translate(' cold drinks'),
                        style: GoogleFonts.elMessiri(
                            textStyle: TextStyle(
                                fontWeight: FontWeight.bold,
                                fontSize: 30.0,
                                color: Colors.white70)),
                      ),
                    ))),
                           Container(
                    decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(15.0),
                      image: DecorationImage(
                        image: AssetImage("assets/images/cold.jfif"),
                        fit: BoxFit.cover,
                        colorFilter: ColorFilter.mode(
                            Colors.black.withOpacity(0.2), BlendMode.darken),
                      ),
                    ),
                    width: 300,
                    height: 180,
                    padding: new EdgeInsets.all(10.0),
                    child: Center(
                        child: GestureDetector(
                      onTap: () {
                        Navigator.push(
                          context,
                          MaterialPageRoute(builder: (context) => coldDrinks()), 
                        );
                      },
                      child: Text(
                        translator.translate(' hot drinks'),
                        style: GoogleFonts.elMessiri(
                            textStyle: TextStyle(
                                fontWeight: FontWeight.bold,
                                fontSize: 30.0,
                                color: Colors.white70)),
                      ),
                    ))),
                SizedBox(
                  height: 10,
                ),
        
                ClipRect(
                  child: Container(
                    color: HexColor("#242424"),
                    height: 30,
                    width: (MediaQuery.of(context).size.width),
                    child: Padding(
                      padding: const EdgeInsets.fromLTRB(10, 5, 10, 5),
                      child: Text(
                        "©2021 All Rights Reserved. Designed and Powered by SWC.",
                        textAlign: TextAlign.center,
                        style: TextStyle(color: Colors.white, fontSize: 12),
                      ),
                    ),
                  ),
                ),
              ])))),
      floatingActionButton: FloatingActionButton(
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => About()),
            );
          },
          backgroundColor: Colors.black,
          child: Icon(
            MdiIcons.information,
            color: Colors.white,
          )),
    );
  }
}

Also try as much as possible to make your build method clean by avoiding putting other functions in the build method. This slows performance of the app.

Asquare17
  • 356
  • 3
  • 9