简体   繁体   中英

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.

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.

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. 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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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