Флаттер: Как вывести короткий текстовый файл из ресурсов на экран телефона? - PullRequest
0 голосов
/ 17 мая 2019

Я просмотрел все ответы о чтении и записи файла во Флаттере.Никто из них не отвечает на вопрос о том, как отобразить текстовый файл на экране телефона.

Все, что я хочу сделать, - это иметь функцию / метод для вызова с именем файла в качестве ввода, которое будет отображатькороткий текстовый файл из моего каталога активов на новом экране телефона, к которому я перешел.Файл правильно размещен в ресурсах и упоминается в файле yaml.Я видел предложение использовать:

Future loadAsset() async {
return await rootBundle.loadString('assets/my_text.txt');
}

, но я не знаю, как его использовать и какой код использовать для отображения файла на экране.

Ответы [ 3 ]

0 голосов
/ 17 мая 2019

Полагаю, вы знаете, как отображать текст на экране, поэтому я просто попытаюсь объяснить, как я обычно читаю файлы.

Сначала вы должны импортировать:

import 'package:path_provider/path_provider.dart';
import 'dart:io';

и затем в своем классе вы можете использовать это:

Future<void> readMyFile() async {
  Directory directory = await getApplicationDocumentsDirectory();
  var _localFilePath = (directory.path + "yourfile.txt");

     if (FileSystemEntity.typeSync(_localFilePath) == FileSystemEntityType.file) {
       final myFile = await _localFile(_localFilePath);
       List<String> linesAsList = await myFile.readAsLinesSync();

    for (var i = 0; i < linesAsList.length; i++) {
      //print("Line No: " + i.toString() + "\n");
      print(linesAsList[i]);
    }
  }
}

Future<File> _localFile(String myPath) async {
  return File(myPath);
}

В конце содержимое вашего файла находится в linesAsList в виде списка строк.

0 голосов
/ 27 мая 2019

Сначала у этого кода появится новый экран и назовите ваш код:

child: 
FlatButton(
  onPressed: () {
    Navigator.pushNamed(context, '/indled');
    setState(() {
      ReadFile(fileName: 'myfile.txt');
      print('Button 1 got pressed');
    });
    },
    ......

Он печатает кнопку 1, которая была нажата на консоли, и переходит на новый экран, на котором есть код:

class Indled extends StatelessWidget {
@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: Text('Indledning'),
  ),
  body: Column(
    crossAxisAlignment: CrossAxisAlignment.stretch,
    children: <Widget>[
      Expanded(
        child: Container(
          padding: EdgeInsets.all(8.0),
          child: Text('Indledning 2'),

Он выводит «Indledning 2» на экран в качестве теста, но больше ничего не происходит. У меня есть ваш код в следующем файле:

class ReadFile {
ReadFile({this.fileName});

final String fileName;

Future<void> readMyFile() async {
Directory directory = await      getApplicationDocumentsDirectory();
var _localFilePath = (directory.path + "myfile.txt");

if (FileSystemEntity.typeSync(_localFilePath) ==
    FileSystemEntityType.file) {
  final myFile = await _localFile(_localFilePath);
  List<String> linesAsList = myFile.readAsLinesSync();

  for (var i = 0; i < linesAsList.length; i++) {
    //print("Line No: " + i.toString() + "\n");
    print(linesAsList[i]);
  }
}
}

Future<File> _localFile(String myPath) async {
return File(myPath);
}
}

В строке: List linesAsList = await myFile.readAsLinesSync (); Жду предупреждения: жду только фьючерса поэтому я вынул ждать. Но тот же результат, если ожидание включено.

Я пытался вставить fileName вместо «my file.txt» в ваш код, но результат тот же.

0 голосов
/ 17 мая 2019

Это мой пример кода:

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

void main() {
  runApp(Test());
}

class Test extends StatefulWidget {
  @override
  _TestState createState() => _TestState();
}

class _TestState extends State<Test> {
  Future _future;

  Future<String> loadString() async =>
      await rootBundle.loadString('assets/text.txt');

  @override
  void initState() {
    _future = loadString();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: FutureBuilder(
            future: _future,
            builder: (context, snapshot) =>
                Text(snapshot.hasData ? '${snapshot.data}' : ' Reading...')),
      ),
    );
  }
}

Вещи, о которых вы должны знать, мы создаем:

Future _future;

Потому что это StatefulWidget и в каждом взаимодействующем классе State перестраивается сам, поэтому ваше приложение будет каждый раз выполнять FutureBuilder, что очень плохо.

Метод loadString является асинхронным с типом возвращаемого значения String. Если вы новичок в Flutter, используйте FutureBuilder для обработки возврата в будущем. Есть и другие способы, более полезные, но немного продвинутые.

Не создавайте виджет, если вы не уверены, что FutureBuilder получает данные с этим условным условием:

snapshot.hasData ? a : b; //or use if(){} else{} for more readable code
...