【问题标题】:flutter: pass clicked page's id and view JSON file颤振:传递点击页面的 id 并查看 JSON 文件
【发布时间】:2022-01-03 21:56:51
【问题描述】:

我正在为餐厅菜单创建一个颤振应用程序,并且我有多个 JSON 文件,其中包含 ex 的数据。饮料、食物和汗水。我的问题是如何仅创建一个颤动页面,以便如果单击主页中的 dinks,它将在第二个屏幕中显示 Drinks.JSON 数据等等......因为现在我为每个 JSON 数据有多个飞镖页面。有没有办法在一个飞镖页面中传递点击页面的 id 并根据它查看 JSON 文件? P.S:所有 JSON 文件都保存在同一个地方 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,
          )),
    );
  }
}

查看数据的第二页:

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,
          )),
    );
  }
}

【问题讨论】:

    标签: flutter


    【解决方案1】:

    您可以将 pageId 作为必需参数传递给小部件。

       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,
                  )),
            );
          }
    }
    

    那么主页应该是这样的。

    //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,
              )),
        );
      }
    }
    

    同时尽量避免在构建方法中加入其他函数,从而使构建方法更加简洁。这会降低应用的性能。

    【讨论】:

      猜你喜欢
      • 2021-03-14
      • 1970-01-01
      • 2021-03-04
      • 2021-08-07
      • 1970-01-01
      • 1970-01-01
      • 2016-08-17
      • 1970-01-01
      • 2023-04-01
      相关资源
      最近更新 更多