简体   繁体   English

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

[英]Display a text string and change it dynamically Flutter/Dart

Basically what i want to do is to display a name taken from a file that contains many others, and after a small delay, the given name changes into another word.基本上我想要做的是显示从包含许多其他文件的文件中获取的名称,并在短暂的延迟后,给定的名称变为另一个词。 The text that i wanna change is inside a Text() widget.我想更改的文本位于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)));
  }
} 

Widget tree:小部件树:

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

As a plus, i'd like to know why passing listOne.length as a parameter to Random.nextInt() generates these 2 errors.另外,我想知道为什么将listOne.length作为参数传递给Random.nextInt()会产生这两个错误。

After running a hot restart:运行热重启后:

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

Running a hot reload after a hot restart:热重启后运行热重载:

'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

readText() is a Future method, you need to await before using its data. readText()是一个 Future 方法,在使用它的数据之前需要等待。 Next thing is we can't tell what should be the response list.接下来的事情是我们无法判断响应列表应该是什么。 We need to act based on list items.我们需要根据列表项采取行动。

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

Use Timer() inside the initState and move the randomIndex line inside the readText() function在 initState 内部使用Timer() initState readText() randomIndex行 function

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM