簡體   English   中英

如何在 map 中存儲有狀態和無狀態小部件列表以及如何訪問特定的鍵值?

[英]How can I store stateful and stateless widget list both in the map and how can access spesific key value?

在我的應用程序中,我必須在 Map 中存儲 statefull 小部件和小部件列表,我該怎么做以及如何從 statefull 小部件訪問列表值,我想使用這種東西 Map<Widget,List> 請幫我。 祝你有美好的一天。

我在下面分享必要的代碼。 第一個代碼是我的主屏幕,當我添加一般餐菜單時,我可以在這里看到,例如添加了“蛋糕”。

import 'package:flutter/material.dart';
import 'package:lezzet_kitabi/add_menu_screen.dart';
import 'package:lezzet_kitabi/constants.dart';
import 'package:lezzet_kitabi/widgets.dart';
import 'package:lezzet_kitabi/make_map.dart';

List<Widget> homeScreenMenuCards=[EmptyMenu(fromWhere:"homeScreen")];

class HomeScreen extends StatefulWidget {
  HomeScreen({this.newMenuName,this.imagePath});
  final  imagePath;
  final  newMenuName;
  static String id="homeScreen";
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  Widget buildBottomSheet(BuildContext context)=>AddMenuScreen(buttonText: "Menü Ekle",route: "homeScreen",);


  void initState(){
    super.initState();
    if (widget.newMenuName!=null && widget.imagePath!=null){
      Widget newMenu=MenuCard(newMenuName: widget.newMenuName,imagePath: widget.imagePath);
      homeScreenMenuCards.insert(0, newMenu);
    }
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        backgroundColor: kColorTheme1,
        appBar: AppBar(
          centerTitle: true,
          automaticallyImplyLeading: false,
          elevation: 20,
          backgroundColor: Color(0xFFF2C3D4).withOpacity(1),
          title:TitleBorderedText(title:"SEVIMLI YEMEKLER", textColor: Color(0xFFFFFB00)),
          actions: [
            CircleAvatar(
              radius: 27,
              backgroundColor: Colors.transparent,
              backgroundImage: AssetImage(kCuttedLogoPath),
            ),
          ],
        ),
        body: Container(
          decoration: BoxDecoration(
            image: DecorationImage(
              image: AssetImage(kBGWithLogoOpacity),
              fit: BoxFit.cover,
            ),
          ),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              Expanded(
                child: GridView.count(
                  crossAxisCount: 2,
                  children:homeScreenMenuCards,
                ),
              ),
              Column(
                mainAxisAlignment: MainAxisAlignment.end,
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: [
                  Padding(
                    padding: EdgeInsets.all(10),
                    child: Container(
                      decoration: BoxDecoration(
                        border: Border.all(style: BorderStyle.solid),
                        color: kColorTheme7,
                        borderRadius: BorderRadius.circular(40),
                      ),
                      child: FlatButton(
                        onPressed: (){
                          showModalBottomSheet(
                              context: context,
                              builder: (BuildContext context)=> AddMenuScreen(buttonText: "Menü Ekle",route: "homeScreen",),
                          );
                        },
                        child: TitleBorderedText(title: "LEZZET GRUBU EKLE",textColor: Colors.white,)
                      ),
                    ),
                  ),
                ],
              )
            ],
          ),
        ),
      ),
    );
  }
}

其次,由於下面的代碼,我通過 givin 參數添加了菜單。

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:lezzet_kitabi/screens/home_screen.dart';
import 'package:lezzet_kitabi/widgets.dart';
import 'constants.dart';
import 'dart:math';
import 'package:lezzet_kitabi/make_map.dart';

class AddMenuScreen extends StatefulWidget {
  AddMenuScreen({@required this.buttonText, @required this.route});
  final route;
  final String buttonText;
  static String id="addMenuScreen";
  @override
  _AddMenuScreenState createState() => _AddMenuScreenState();
}

class _AddMenuScreenState extends State<AddMenuScreen> {
  int selectedIndex=-1;
  Color _containerForStickersInactiveColor=Colors.white;
  Color _containerForStickersActiveColor=Colors.black12;
  final stickerList= List<String>.generate(23, (index) => "images/sticker$index");
  String chosenImagePath;
  String menuName;
  int addScreenImageNum;


  void initState(){
    super.initState();
    createAddScreenImageNum();
  }

  void createAddScreenImageNum(){
    Random random =Random();
    addScreenImageNum = random.nextInt(3)+1;
  }

  @override
  Widget build(BuildContext context) {
    return Material(
      child: Container(
        color: kColorTheme9,
        child: Container(
          height: 400,
          decoration: BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.only(topRight: Radius.circular(40),topLeft: Radius.circular(40)),
          ),
          child:Padding(
            padding:EdgeInsets.all(20.0),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              mainAxisAlignment: MainAxisAlignment.start,
              children: [
                Container(
                  decoration: BoxDecoration(
                    color: kColorTheme2,
                    borderRadius: BorderRadius.circular(90)
                  ),
                  child: TextField(
                    style: TextStyle(
                      color: Colors.black,
                      fontFamily:"Graduate",
                      fontSize: 20,
                    ),
                    textAlign: TextAlign.center,
                    onChanged: (value){
                      menuName=value;
                    },
                    decoration: InputDecoration(
                      border:OutlineInputBorder(
                        borderRadius: BorderRadius.circular(90),
                        borderSide: BorderSide(
                        color: Colors.teal,
                        ),
                      ),
                      hintText: "Menü ismi belirleyin",
                      hintStyle: TextStyle(
                        color: Colors.black.withOpacity(0.2),
                        fontFamily: "Graduate",
                      ),
                    ),
                  ),
                ),
                SizedBox(height: 20,),
                Text(" yana kadırarak menünüz icin bir resim secin",textAlign: TextAlign.center,
                  style: TextStyle(fontFamily: "Graduate", fontSize: 12),),
                SizedBox(height: 20,),
                Expanded(
                  child: ListView.builder(
                    scrollDirection: Axis.horizontal,
                    itemCount: stickerList.length,
                    itemBuilder: (context,index){
                      return Container(
                        decoration: BoxDecoration(
                          borderRadius: BorderRadius.circular(30),
                          color: index == selectedIndex ?
                          _containerForStickersActiveColor :
                          _containerForStickersInactiveColor,
                        ),
                        child:TextButton(
                          child: Image(
                            image: AssetImage("images/sticker$index.png"),
                          ),
                          onPressed: (){
                            setState(() {
                              selectedIndex = index;
                            });
                          },
                        ),
                        );
                      }
                    ),
                  ),
                SizedBox(height: 20,),
                Container(
                  decoration: BoxDecoration(
                    border: Border.all(style: BorderStyle.solid),
                    color: kColorTheme7,
                    borderRadius: BorderRadius.circular(90),
                  ),
                  child: TextButton(
                    onPressed: (){
                      if(widget.route=="homeScreen"){
                        Navigator.push(context, MaterialPageRoute(builder: (context)=>HomeScreen(newMenuName: menuName,imagePath: "images/sticker$selectedIndex.png")));
                      }
                      else if(widget.route=="menuExtensionScreen"){
                        Navigator.push(context, MaterialPageRoute(builder: (context)=>MenuExtensionScreen(menuExtensionName: menuName, imagePath: "images/sticker$selectedIndex.png",)));
                      }
                    },
                    child: Text(widget.buttonText, style: TextStyle(fontSize: 20, color:  Colors.white,
                        fontFamily: "Graduate", fontWeight: FontWeight.bold),),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

我的主要問題是當我在主屏幕中創建一個菜單時,例如“蛋糕”,我希望它構建蛋糕屏幕構建,當我將新菜單添加到主屏幕后,也必須構建它。 多虧了下面的小部件,我才能解決這個問題。 但是,我如何存儲下面的頁面,我如何選擇頁面和菜單卡列表,當用戶創建並點擊新菜單時將返回,請幫我我卡住了。 謝謝你。 祝你今天過得愉快。

import 'package:flutter/material.dart';
import 'dart:math';
import 'add_menu_screen.dart';
import 'package:bordered_text/bordered_text.dart';
import 'constants.dart';
import 'package:lezzet_kitabi/make_map.dart';

List<Widget> menuExtensionScreens=[];

class MenuCard extends StatelessWidget {
  MenuCard({this.newMenuName, this.imagePath, });
  final newMenuName;
  final imagePath;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.only(top:15.0),
      child: TextButton(
        onPressed: (){
          MenuExtensionScreen menuExtensionScreen=MenuExtensionScreen(menuExtensionName: newMenuName);
          menuExtensionScreens.add(menuExtensionScreen);
          Navigator.push(context, MaterialPageRoute(builder: (context)=>MenuExtensionScreen(menuExtensionName: newMenuName,)));
        },
        child: Container(
          height: 180,
          width: 180,
          decoration: BoxDecoration(
            border: Border.all(style: BorderStyle.solid, width: 1),
            borderRadius: BorderRadius.circular(30),
            color: Color((Random().nextDouble() * 0xFFFFFF).toInt()).withOpacity(0.5),
          ),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              SizedBox(height: 10,),
              Container(
                decoration: BoxDecoration(
                  color: Colors.white.withOpacity(0.5),
                  borderRadius: BorderRadius.circular(90),
                ),
                child: Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Text(
                    newMenuName,
                    style: TextStyle(
                        color: Colors.black,
                        fontSize: 20,
                        fontFamily: 'Graduate',
                        fontWeight: FontWeight.bold),
                  ),
                ),
              ),
              Expanded(
                child: Padding(
                  padding:EdgeInsets.all(5),
                  child: Image(
                    image: AssetImage(
                        imagePath
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
class EmptyMenu extends StatelessWidget {
  EmptyMenu({this.fromWhere});
  final String fromWhere;
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.only(top:15.0),
      child: TextButton(
        onPressed: (){
          if(fromWhere=="homeScreen"){
            showModalBottomSheet(
              context: context,
              builder: (BuildContext context)=> AddMenuScreen(buttonText: "Menü Ekle",route:"homeScreen"),
            );
          }
          else if(fromWhere=="menuExtension"){
            showModalBottomSheet(
              context: context,
              builder: (BuildContext context)=> AddMenuScreen(buttonText: "Tarif Ekle",route:"menuExtensionScreen"),
            );
          }
        },
        child: Container(
          height: 180,
          width: 180,
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(30),
            color: Colors.black12.withOpacity(0.1),
          ),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              Icon(Icons.add_circle_outline_outlined,size: 100,color: Colors.grey.shade400,),
            ],
          ),
        ),
      ),
    );
  }
}

class MenuExtensionScreen extends StatefulWidget {
  MenuExtensionScreen({this.menuExtensionName, this.imagePath});

  final String imagePath;
  final String menuExtensionName;
  @override
  _MenuExtensionScreenState createState() => _MenuExtensionScreenState();
}

class _MenuExtensionScreenState extends State<MenuExtensionScreen> {
  List<Widget> menuExtensionCards=[EmptyMenu(fromWhere: "menuExtension")];

  void initState(){
    super.initState();
    if (widget.menuExtensionName!=null && widget.imagePath!=null){
      Widget newMenu=MenuCard(newMenuName: widget.menuExtensionName,imagePath: widget.imagePath);
      menuExtensionCards.insert(0, newMenu);
    }
  }

  Widget buildBottomSheet(BuildContext context)=>AddMenuScreen(buttonText: "Tarif Ekle",route: "menuExtensionScreen",);
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        appBar: AppBar(
          automaticallyImplyLeading: false,
          centerTitle: true,
          title: BorderedText(
            child:Text(
              widget.menuExtensionName,
              style: TextStyle(
                  color: Color(0XFFFFFB00),
                  fontSize: 30,
                  fontFamily: "Graduate"
              ),
            ),
            strokeWidth: 5,
            strokeColor: Colors.black,
          ),
          elevation: 5,
          backgroundColor: Color(0xFFF2C3D4).withOpacity(1),
          leading: IconButton(
            icon: Icon(Icons.arrow_back),
            onPressed: (){
              Navigator.pop(context);
            },
            iconSize: 40,
            color: Color(0xFFA2000B),
          ),
          actions: [
            CircleAvatar(
              radius: 27,
              backgroundColor: Colors.transparent,
              backgroundImage: AssetImage("images/cuttedlogo.PNG"),
            )
          ],
        ),
        body: Container(
          decoration: BoxDecoration(
            image: DecorationImage(
              image: AssetImage("images/logoBGopacity.png"),
              fit: BoxFit.cover,
            ),
          ),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              Expanded(
                child: GridView.count(
                  crossAxisCount: 2,
                  children:menuExtensionCards,
                ),
              ),
              Column(
                mainAxisAlignment: MainAxisAlignment.end,
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: [
                  Padding(
                    padding: EdgeInsets.all(10),
                    child: Container(
                      decoration: BoxDecoration(
                        border: Border.all(style: BorderStyle.solid),
                        color: kColorTheme7,
                        borderRadius: BorderRadius.circular(40),
                      ),
                      child: TextButton(
                        onPressed: (){
                          showModalBottomSheet(
                            context: context,
                            builder: (BuildContext context)=> AddMenuScreen(buttonText: "Tarif Ekle", route:"menuExtension"),
                          );
                        },
                        child: BorderedText(
                          strokeWidth: 5,
                          strokeColor: Colors.black,
                          child:Text("Tarif Ekle",style: TextStyle(
                            color: Colors.white,
                            fontFamily:'Graduate',
                            fontSize:30,
                          ),
                          ),
                        ),
                      ),
                    ),
                  ),
                ],
              )
            ],
          ),
        ),
      ),
    );
  }
}

我想你想要類似的東西。 在這里,我使用了一個名為provider的 state 管理。

import 'dart:collection';

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<MenusProvider>(
      create: (_) => MenusProvider(),
      child: MaterialApp(
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: HomePage(),
      ),
    );
  }
}

class Menu {
  const Menu(
    this.name,
    this.imagePath,
  );

  final String name;
  final String imagePath;
}

class MenusProvider extends ChangeNotifier {
  final List<Menu> _menus = <Menu>[];

  UnmodifiableListView<Menu> get menus => UnmodifiableListView<Menu>(_menus);

  int get menusCount => _menus.length;

  void addMenu(Menu menu) {
    _menus.add(menu);
    notifyListeners();
  }

  void delete(Menu menu) {
    if (_menus.remove(menu)) {
      notifyListeners();
    }
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: HomeScreen(),
      ),
    );
  }
}

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: Consumer<MenusProvider>(
          child: IconButton(
            onPressed: () {
              showModalBottomSheet(
                context: context,
                builder: (_) => Container(
                  height: 100,
                  child: RaisedButton(
                    onPressed: () {
                      final MenusProvider provider =
                          Provider.of<MenusProvider>(context, listen: false);
                      provider.addMenu(Menu('Menu ${provider.menusCount}', ''));
                      Navigator.pop(context);
                    },
                    child: const Text('Add menu'),
                  ),
                ),
              );
            },
            icon: const Icon(Icons.add),
          ),
          builder: (_, MenusProvider provider, Widget child) => GridView.count(
            crossAxisCount: 2,
            children: <Widget>[
              ...provider.menus
                  .map((Menu menu) => Card(
                        child: Center(child: Text(menu.name)),
                      ))
                  .toList(),
              child,
            ],
          ),
        ),
      ),
    );
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM