[FIXED] Die Daten aus der lokalen Datei werden in initSate nicht aktualisiert

Ausgabe

Ich baue die App, die den Baum der miteinander verbundenen Blöcke zurückgeben soll. Ich möchte die Möglichkeit haben, die Informationen zu speichern, nachdem der Benutzer die Änderungen am Telefon vorgenommen hat. Ich verwende dafür getApplicationDocumentsDirectory(), um den Pfad zu erhalten. Nachdem der Benutzer Änderungen vorgenommen und die App geschlossen hat, kann er sie öffnen und seinen gesamten Fortschritt sehen. Also versuche ich die Datei asynchron in initState() zu lesen

Ich habe alles versucht: FutureBuilder; anonyme asynchrone Funktionen in initState; dann; wennVollständig. Ich habe die ganze Zeit das gleiche Ergebnis: Die Informationen werden gelesen, nachdem der Baum erstellt wurde.

Könnt ihr mir dabei helfen? (Mein Code ist unten; Jetzt gibt er einen Typfehler zurück, aber ich weiß nicht, wie ich ihn lösen soll.)

main.dart

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:graphview/GraphView.dart';
import 'dart:math';
import 'MyNode.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) => MaterialApp(
        home: TreeViewPage(),
      );
}

class TreeViewPage extends StatefulWidget {
  @override
  _TreeViewPageState createState() => _TreeViewPageState();
}

var parsedJson;

final Graph graph = Graph()..isTree = true;
SugiyamaConfiguration builder = SugiyamaConfiguration();
// builder
//   ..levelSeparation = (150)
//   ..nodeSeparation = (100)
//   ..orientation = (SugiyamaConfiguration.ORIENTATION_TOP_BOTTOM);
List<MyNode> ListMyNode = [];
int nodesCount = 0;

String text_from_init_state = "no_data";

class _TreeViewPageState extends State {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FutureBuilder(
        future: parsedJson,
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (parsedJson == null) {
            return Center(
              child: CircularProgressIndicator(
                  backgroundColor: Colors.red,
                  valueColor: AlwaysStoppedAnimation<Color>(Colors.blue)),
            );
          }

          return Column(
            mainAxisSize: MainAxisSize.max,
            children: [
              Text(text_from_init_state),
              Expanded(
                child: InteractiveViewer(
                  constrained: false,
                  boundaryMargin: EdgeInsets.all(300),
                  minScale: 0.01,
                  maxScale: 5.6,
                  child: GraphView(
                    graph: graph,
                    algorithm: SugiyamaAlgorithm(builder),
                    paint: Paint()
                      ..color = Colors.green
                      ..strokeWidth = 1
                      ..style = PaintingStyle.stroke,
                    builder: (Node node) {
                      // I can decide what widget should be shown here based on the id
                      var a = node.key!.value as int;
                      return rectangleWidget(a);
                    },
                  ),
                ),
              ),
            ],
          );
        },
      ),
    );
  }

  Widget rectangleWidget(int a) {
    TextEditingController textController = TextEditingController();
    if (ListMyNode[a - 1].text != "") {
      textController.text = ListMyNode[a - 1].text;
    }

    return InkWell(
      onTap: () {
        print("a" + a.toString());
      },
      child: Container(
        padding: EdgeInsets.all(20),
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(4),
          boxShadow: [
            BoxShadow(color: Colors.blue, spreadRadius: 1),
          ],
        ),
        child: Column(
          children: [
            Container(
              // height: 80,
              width: 80,
              child: TextField(
                keyboardType: TextInputType.multiline,
                maxLines: null,
                controller: textController,
                decoration: const InputDecoration(),
                onChanged: (v) async {
                  await ListMyNode[a - 1].UpdateText(v, ListMyNode);
                },
              ),
            ),
            Container(
              alignment: Alignment.bottomRight,
              child: IconButton(
                icon: Icon(Icons.add_box_rounded),
                iconSize: 24,
                onPressed: () async {
                  nodesCount++;
                  final newNode = Node.Id(nodesCount);
                  var edge = graph.getNodeAtPosition(a - 1);
                  graph.addEdge(edge, newNode);
                  text_from_init_state = await readJson();
                  setState(() {
                    MyNode b = MyNode(nodesCount, "");
                    ListMyNode.add(b);
                  });
                },
              ),
            ),
          ],
        ),
      ),
    );
  }

  @override
  void initState() {
    readJson2().whenComplete(() {
      print("PArsed Json: " + parsedJson.toString());

      if (parsedJson == "{}") {
        final node1 = Node.Id(1);
        final node2 = Node.Id(2);
        MyNode block0 = MyNode(nodesCount, "empty1");
        nodesCount++;
        MyNode block1 = MyNode(nodesCount, "empty2");
        nodesCount++;
        ListMyNode.add(block0);
        ListMyNode.add(block1);
        graph.addEdge(node1, node2);
      } else {
        final node1 = Node.Id(1);
        final node2 = Node.Id(2);
        MyNode block0 = MyNode(nodesCount, parsedJson.toString());
        nodesCount++;
        MyNode block1 = MyNode(nodesCount, "not_empty2");
        nodesCount++;
        ListMyNode.add(block0);
        ListMyNode.add(block1);
        graph.addEdge(node1, node2);
      }

      print("before setState: " + parsedJson);
      setState(() {});
      print("after setState: " + parsedJson);
    });
    super.initState();

    builder
      ..levelSeparation = (150)
      ..nodeSeparation = (100)
      ..orientation = (SugiyamaConfiguration.ORIENTATION_TOP_BOTTOM);
  }

  Future<void> readJson2() async {
    try {
      final file = await localFile();

      // Read the file
      final contents = await file.readAsString();

      parsedJson = contents;
    } catch (e) {
      // If encountering an error, return 0
      parsedJson = "{}";
    }
  }
}

MyNode.dart

import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';

String ListMyNodeJSON(List<MyNode> lst) {
  Map<int, String> mapMyNodeJSON = {};
  for (int i = 0; i < lst.length; i++) {
    mapMyNodeJSON[lst[i].id] = lst[i].text;
  }
  return mapMyNodeJSON.toString();
}

Future<String> localPath() async {
  final directory = await getApplicationDocumentsDirectory();

  return directory.path;
}

Future<File> localFile() async {
  final path = await localPath();
  return File('$path/tree.json');
}

Future<File> writeJson(text) async {
  final file = await localFile();
  return file.writeAsString("$text");
}

Future<String> readJson() async {
  try {
    final file = await localFile();

    // Read the file
    final contents = await file.readAsString();

    return contents;
  } catch (e) {
    // If encountering an error, return 0
    return "{}";
  }
}

class MyNode {
  int id = 0;
  String text = "";

  MyNode(int id, String text) {
    this.id = id;
    this.text = text;
  }

  Future<void> UpdateText(String text, List<MyNode> lst) async {
    this.text = text;
    await writeJson(ListMyNodeJSON(lst));
  }

  String toString() {
    return this.id.toString() + "---" + this.text;
  }
}

Lösung

Ich habe Ihren Code aktualisiert, um beim Abrufen von Daten einen Ladebalken anzuzeigen und nach Abschluss Blöcke anzuzeigen. Jetzt erhält es den Fortschritt aus der Datei, aber es scheint, dass Sie die Spiellogik zum Fortsetzen des Fortschritts noch nicht implementiert haben. Ich finde das ein interessantes Projekt. Hoffen Sie, dass dieser Code Ihr Problem löst, und entwickeln Sie den Fortschrittslogikabschnitt weiter.

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:graphview/GraphView.dart';
import 'dart:math';
import 'MyNode.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) => MaterialApp(
        home: TreeViewPage(),
      );
}

class TreeViewPage extends StatefulWidget {
  @override
  _TreeViewPageState createState() => _TreeViewPageState();
}

final Graph graph = Graph()..isTree = true;
SugiyamaConfiguration builder = SugiyamaConfiguration();
// builder
//   ..levelSeparation = (150)
//   ..nodeSeparation = (100)
//   ..orientation = (SugiyamaConfiguration.ORIENTATION_TOP_BOTTOM);
List<MyNode> ListMyNode = [];
int nodesCount = 0;

String text_from_init_state = "no_data";

class _TreeViewPageState extends State {
  late String parsedJson;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FutureBuilder(
        future: readJson2(),
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Center(
              child: CircularProgressIndicator(
                  backgroundColor: Colors.red,
                  valueColor: AlwaysStoppedAnimation<Color>(Colors.blue)),
            );
          } else if (snapshot.connectionState == ConnectionState.done) {
            parsedJson = snapshot.data as String;
            updateNode(parsedJson);
            return Column(
              mainAxisSize: MainAxisSize.max,
              children: [
                Text(text_from_init_state),
                Expanded(
                  child: InteractiveViewer(
                    constrained: false,
                    boundaryMargin: EdgeInsets.all(300),
                    minScale: 0.01,
                    maxScale: 5.6,
                    child: GraphView(
                      graph: graph,
                      algorithm: SugiyamaAlgorithm(builder),
                      paint: Paint()
                        ..color = Colors.green
                        ..strokeWidth = 1
                        ..style = PaintingStyle.stroke,
                      builder: (Node node) {
                        // I can decide what widget should be shown here 
                        //based on the id
                        var a = node.key!.value as int;
                        return rectangleWidget(a);
                      },
                    ),
                  ),
                ),
              ],
            );
          }
          return Center(
            child: Text(
              'Something went wrong!',
              style: TextStyle(
                color: Colors.red,
              ),
            ),
          );
        },
      ),
    );
  }

  void updateNode(String parsedReadJson2) {
    if (parsedReadJson2.isEmpty) {
      final node1 = Node.Id(1);
      final node2 = Node.Id(2);
      MyNode block0 = MyNode(nodesCount, "empty1");
      nodesCount++;
      MyNode block1 = MyNode(nodesCount, "empty2");
      nodesCount++;
      ListMyNode.add(block0);
      ListMyNode.add(block1);
      graph.addEdge(node1, node2);
    } else {
      final node1 = Node.Id(1);
      final node2 = Node.Id(2);
      MyNode block0 = MyNode(nodesCount, parsedReadJson2.toString());
      nodesCount++;
      MyNode block1 = MyNode(nodesCount, "not_empty2");
      nodesCount++;
      ListMyNode.add(block0);
      ListMyNode.add(block1);
      graph.addEdge(node1, node2);
    }
  }

  Widget rectangleWidget(int a) {
    TextEditingController textController = TextEditingController();
    if (ListMyNode[a - 1].text != "") {
      textController.text = ListMyNode[a - 1].text;
    }

    return InkWell(
      onTap: () {
        print("a$a");
      },
      child: Container(
        padding: EdgeInsets.all(20),
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(4),
          boxShadow: [
            BoxShadow(color: Colors.blue, spreadRadius: 1),
          ],
        ),
        child: Column(
          children: [
            Container(
              // height: 80,
              width: 80,
              child: TextField(
                keyboardType: TextInputType.multiline,
                maxLines: null,
                controller: textController,
                decoration: const InputDecoration(),
                onChanged: (v) async {
                  await ListMyNode[a - 1].UpdateText(v, ListMyNode);
                },
              ),
            ),
            Container(
              alignment: Alignment.bottomRight,
              child: IconButton(
                icon: Icon(Icons.add_box_rounded),
                iconSize: 24,
                onPressed: () async {
                  nodesCount++;
                  final newNode = Node.Id(nodesCount);
                  var edge = graph.getNodeAtPosition(a - 1);
                  graph.addEdge(edge, newNode);
                  text_from_init_state = await readJson();
                  setState(() {
                    MyNode b = MyNode(nodesCount, "");
                    ListMyNode.add(b);
                  });
                },
              ),
            ),
          ],
        ),
      ),
    );
  }

  @override
  void initState() {
    super.initState();

    builder
      ..levelSeparation = (150)
      ..nodeSeparation = (100)
      ..orientation = (SugiyamaConfiguration.ORIENTATION_TOP_BOTTOM);
  }

  Future<String> readJson2() async {
    try {
      final file = await localFile();

      // Read the file
      final contents = await file.readAsString();

      return contents;
    } catch (e) {
      // If encountering an error, return empty string
      return '';
    }
  }
}


Beantwortet von –
Ye Lwin Oo


Antwort geprüft von –
Senaida (FixError Volunteer)

0 Shares:
Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like