显示文本字符串并动态更改它 Flutter/Dart

Display a text string and change it dynamically Flutter/Dart

基本上我想做的是显示从包含许多其他文件的文件中获取的名称,经过一小段延迟后,给定名称变为另一个词。我想更改的文本位于 Text() 小部件内。

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

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

/*
 *  Retriving data from file, picking a random word and assign it to dataFromFile
 */

class _ReadTextFileState extends State<ReadTextFile> {

  String dataFromFile = "";
  static List<String> listOne = []; //contains all jobs.txt content, from top to bottom
  int randomIndex = Random().nextInt(1027); //quick fix to "RangeError" thrown by Random().nextInt(listOne.length)

  Future<void> readText() async {
    final String response = await rootBundle.loadString('assets/jobs.txt');
    listOne = response.split(',');
    setState(() {
      dataFromFile = listOne[randomIndex];
    });
  }

  @override
  Widget build(BuildContext context) {
    readText();
    // showRandomJob();
    return Container(child: Center(child: Text(dataFromFile)));
  }
} 

小部件树:

import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final appTitle = 'ListGenerator';

    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          foregroundColor: Color.fromARGB(255, 32, 75, 132),
          title: Text(appTitle),
          centerTitle: true,
          backgroundColor: Color.fromARGB(255, 11, 161, 242),
        ),
        body: Column(
          children: const[
             Expanded(
                flex: 1,
                child: SingleChildScrollView(
                  scrollDirection: Axis.vertical,
                  child: ReadTextFile(),
                )),
          ],
        ),
      ),
    );
  }
 
}

另外,我想知道为什么将 listOne.length 作为参数传递给 Random.nextInt() 会产生这两个错误。

运行 热重启后:

RangeError (max): Must be positive and <= 2^32: Not in inclusive range 1..4294967296:
0
See also: https://flutter.dev/docs/testing/errors

运行 热重启后的热重载:

'package:flutter/src/widgets/framework.dart': Failed assertion: line 6205 pos 12: 'child == _child': is not true. See also: https//flutter.dev/docs/testing/errors

initState 中使用 Timer() 并在 readText() 函数中移动 randomIndex

import 'dart:async';
import 'dart:math';

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

class ReadTextFile extends StatefulWidget {
  @override
  _ReadTextFileState createState() => _ReadTextFileState();
}

class _ReadTextFileState extends State<ReadTextFile> {

  String dataFromFile = "";
  static List<String> listOne = [];

  Future<void> readText() async {
    final String response = await rootBundle.loadString('assets/jobs.txt');
    listOne = response.split(',');
    int randomIndex = Random().nextInt(listOne.length);
    setState(() {
      dataFromFile += listOne[randomIndex]+", ";
    });
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    Timer.periodic(Duration(seconds: 1), (val) async {
      await readText();
    });
  }
  
  @override
  Widget build(BuildContext context) {
    return Container(child: Center(child: Text(dataFromFile)));
  }
}

readText() 是一个 Future 方法,在使用它的数据之前需要等待。接下来的事情是我们无法判断响应列表应该是什么。我们需要根据列表项采取行动。

class _ReadTextFileState extends State<ReadTextFile> {
  String dataFromFile = "";
  static List<String> listOne = [];

  Future<void> readText() async {
    final String response = await rootBundle.loadString('assets/jobs.txt');
    listOne = response.split(',');

    int c = 0;
    if (listOne.isEmpty) return;
    Timer.periodic(Duration(seconds: 1), (timer) {
      if (c == listOne.length - 1) {
        timer.cancel();
        return;
      }
      if (c != 0) dataFromFile += ",";
      dataFromFile += listOne[c];
      c++;
      setState(() {});
    });
  }

  void initData() async {
    await readText();
  }

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

  @override
  Widget build(BuildContext context) {
    return Container(child: Center(child: Text(dataFromFile)));
  }
}