dart 在另一个屏幕中按下保存按钮后,如何在主屏幕中创建循环图?

yebdmbv4  于 2024-01-04  发布在  其他
关注(0)|答案(2)|浏览(115)

我用flutter编程一个应用程序,我有点卡在ATM机上。我在想:我有一个主屏幕,它有一个浮动AcctionButton。如果你按下这个,另一个屏幕将打开,在那里你可以写一些数据(可以把它想象成一个公式)。只要你在第二个屏幕中按下保存按钮,一个ciruclar文件就会在主屏幕中创建,它的功能就像一个容器,保存公式的地方。应该可以有几个公式,所以你把它们放在一起。
这是我的代码:

首页

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../widgets/add_goal_button.dart';
import '../widgets/goal_app_bar.dart';

class HomescreenWidget extends StatefulWidget {
  const HomescreenWidget({Key? key}) : super(key: key);

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

class _HomescreenWidgetState extends State<HomescreenWidget> {
  final scaffoldKey = GlobalKey<ScaffoldState>();
  late FocusNode unfocusNode;

  @override
  void initState() {
    super.initState();
    unfocusNode = FocusNode();
  }

  @override
  void dispose() {
    unfocusNode.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    if (Theme.of(context).platform == TargetPlatform.iOS) {
      SystemChrome.setSystemUIOverlayStyle(
        SystemUiOverlayStyle(
          statusBarBrightness: Theme.of(context).brightness,
          systemStatusBarContrastEnforced: true,
        ),
      );
    }

    return GestureDetector(
      onTap: () => unfocusNode.canRequestFocus
          ? FocusScope.of(context).requestFocus(unfocusNode)
          : FocusScope.of(context).unfocus(),
      child: Scaffold(
        backgroundColor: Colors.white,
        key: scaffoldKey,
        appBar: GoalAppBar(),
        body: SafeArea(
          top: true,
          child: Stack(
            children: [
              AddGoalButton(),
            ],
          ),
        ),
      ),
    );
  }
}

字符串

清单

import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:flutter/services.dart';
import '../utils/theme_utils.dart';
import 'dart:io';

import 'homescreen.dart';

class Checklist extends StatefulWidget {
  const Checklist({super.key});

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

class _ChecklistState extends State<Checklist> {
  List<bool> checkBoxValues = [false, false, false, false, false];
  File? selectedImage;

  Future<void> _pickImage() async {
    final imagePicker = ImagePicker();
    try {
      final pickedFile = await imagePicker.pickImage(source: ImageSource.gallery);
      if (pickedFile != null) {
        setState(() {
          selectedImage = File(pickedFile.path);
        });
      }
    } on PlatformException catch (e) {
      print("Fehler beim Bildauswählen: $e");
    }
  }

  void _createCircleDiagram() {
    Navigator.push(
      context,
      MaterialPageRoute(builder: (context) => const HomescreenWidget()),
      //TODO
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Ziel"),
        backgroundColor: ThemeUtils.baseColor,
        actions: [
          IconButton(
            icon: const Icon(Icons.save),
            onPressed: () {
              _createCircleDiagram();
            },
          ),
        ],
      ),
      body: SingleChildScrollView(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const Padding(
              padding: EdgeInsets.all(16.0),
              child: Text(
                "Mein SMARTes Ziel",
                style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
              ),
            ),
            Container(
              margin: const EdgeInsets.all(16),
              padding: const EdgeInsets.all(8),
              decoration: BoxDecoration(
                border: Border.all(color: Colors.grey),
              ),
              child: const TextField(
                keyboardType: TextInputType.multiline,
                maxLines: null,
                decoration: InputDecoration(
                  hintText: "Dein Text hier...",
                  border: InputBorder.none,
                ),
              ),
            ),
            const Padding(
              padding: EdgeInsets.all(16.0),
              child: Text(
                "Aktivitäten",
                style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
              ),
            ),
            Container(
              margin: const EdgeInsets.all(16),
              child: Column(
                children: List.generate(5, (index) {
                  return Row(
                    children: [
                      Checkbox(
                        value: checkBoxValues[index],
                        onChanged: (bool? value) {
                          setState(() {
                            checkBoxValues[index] = value ?? false;
                          });
                        },
                      ),
                      Expanded(
                        child: Container(
                          margin: const EdgeInsets.only(left: 8),
                          padding: const EdgeInsets.all(8),
                          decoration: BoxDecoration(
                            border: Border.all(color: Colors.grey),
                          ),
                          child: TextField(
                            keyboardType: TextInputType.multiline,
                            maxLines: null,
                            decoration: InputDecoration(
                              hintText: "Aktivität $index...",
                              border: InputBorder.none,
                            ),
                          ),
                        ),
                      ),
                    ],
                  );
                }),
              ),
            ),
            const Padding(
              padding: EdgeInsets.all(16.0),
              child: Text(
                "Mein Glaube",
                style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
              ),
            ),
            Container(
              margin: const EdgeInsets.all(16),
              child: GestureDetector(
                onTap: _pickImage,
                child: Container(
                  height: 200,
                  decoration: BoxDecoration(
                    border: Border.all(color: Colors.grey),
                  ),
                  child: selectedImage != null
                      ? Image.file(selectedImage!)
                      : const Center(
                    child: Text("Bild auswählen"),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

z9smfwbn

z9smfwbn1#

@HatGuy我会用这个按钮创建一个主页。在onPressed上,使用()=> context.go(字符串路由)。此外,创建一个MyFormPage,实现Form小部件,并将Column/ListView作为子部件。在这里,您可以使用图像选择器,文本表单字段等。小部件将声明一个GlobalKey,并在保存按钮处,您可以执行_formState.保存()并返回主页。保存的字段可以作为参数传递给路由器,也可以保存在状态管理器中,如Bloc等。
在主页中,如果字段不为空,则可以加载循环图。有用于此的库,例如https://pub.dev/packages/circular_chart_flutter
希望能帮上忙!

j2datikz

j2datikz2#

您可以通过在导航中将值作为参数传递来实现这一点。
在HomeScreen.dart中,在按钮按下的函数中添加以下代码。

//Global variables
List<bool> checkBoxValues;
File? selectedImage

ElevatedButton(
                onPressed: () async {
                  Map<String, dynamic> map = await Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (context) => const Checklist(),
                    ),
                  );
                  setState(() {
                    checkBoxValues = map['checkBoxValues'];
                    selectedImage = map['selectedImage'];
                  });
                },
                child: const Text('Second Screen'),
              ),

字符串
在上面的代码中,Navigator.push()函数前添加了await关键字,并添加了onPressed关键字,使onPressed函数成为Future,await关键字将等待SecondScreen(在本例中为CheckList)弹出并传递带有 checkBoxValuesselectedImage 等值的Map.您可以使用SecondScreen返回的map访问这些值,并将其分配给全局变量,然后调用**setState()**重建UI;
在第二个屏幕中,单击保存时的功能应为:

void _createCircleDiagram() {
    Map<String, dynamic> map = {
      'checkBoxValues': checkBoxValues,
      'selectedImage': selectedImage
    };
    Navigator.pop(context, map);
    // Navigator.push(
    //   context,
    //   MaterialPageRoute(builder: (context) => const HomescreenWidget()),
    //   //TODO
    // );
  }


创建一个Map,它将保存所有你需要传递到第一个屏幕的值。同样,你可以通过Map传递文本字段中的任何文本值。
其次,您可以使用**Navigator.pop()而不是Navigator.push()**返回主屏幕。
pop用于从堆栈中弹出当前屏幕,因此它将关闭第二个屏幕并返回到第一个屏幕。
如果您在第二个屏幕中使用push,第一个页面将再次创建,从而在堆栈的第一个和最后一个屏幕上创建两个第一个屏幕。
现在,每当您在单击保存按钮时调用该函数时,将创建一个包含值的map,并将其作为第二个参数传递给Navigator.pop()函数。然后,将在HomeScreen中检索相同的map,并根据接收到的值设置视图。

相关问题