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
CodePudding user response:
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() {
super.initState();
// change text after 1 sec
Timer(Duration(seconds: 1), ()=>readText());
}
@override
Widget build(BuildContext context) {
return Container(child: Center(child: Text(dataFromFile)));
}
}
CodePudding user response:
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(',');
setState(() {
if (listOne.length > 2) {
dataFromFile = listOne[Random().nextInt(listOne.length - 1)];
} else if (listOne.length == 1) {
dataFromFile = listOne.first;
}
});
debugPrint(listOne.toString());
}
void initData() async {
await readText();
}
@override
void initState() {
super.initState();
initData();
}
@override
Widget build(BuildContext context) {
return Container(child: Center(child: Text(dataFromFile)));
}
}