Как отобразить ListTile после сохранения данных в локальной базе данных не из api?

#flutter #dart #flutter-layout #flutter-dependencies #dart-pub

#flutter #dart #flutter-layout #flutter-зависимости #dart-pub

Вопрос:

Я использую пакет flutter_ffmpeg для извлечения метаданных песен. В моем приложении пользователь может выбирать песни из внутреннего хранилища, а затем извлекать метаданные с помощью flutter_ffmpeg, хранящиеся в локальных списках. Я использую эти списки для создания своего пользовательского виджета (фрагменты песен с именем исполнителя, продолжительностью и т. Д.). В моем случае все виджеты сначала отображаются с нулевым списком Я хочу отобразить виджет после того, как все метаданные выбранных песен будут сохранены в списке, а затем смогут отображать виджет. Как это заархивировать?

Поскольку я не использую API, я не могу использовать виджет Builder. Пожалуйста, помогите.

Код: https://pastebin.com/gwZkuujA Виджет CustomSongTile : https://pastebin.com/edit/ZSi25ydz

 import 'package:audiobook_player/presentation/pages/widgets/book_info_tile.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter_ffmpeg/flutter_ffmpeg.dart';

class FilePickerTrial extends StatelessWidget {
  final FlutterFFprobe _flutterFFprobe = new FlutterFFprobe();
  final List<String> audioPaths = [];
  final List<String> audioTitle = [];
  final List<String> audioAuthor = [];
  final List<String> audioDuration = [];
  FilePickerTrial({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    Size size = MediaQuery.of(context).size;
    return Container(
      child: Scaffold(
        appBar: AppBar(
          actions: [
            Container(
              width: size.width,
              child: Padding(
                padding: const EdgeInsets.all(8.0),
                child: Row(
                  mainAxisSize: MainAxisSize.max,
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    Align(
                      alignment: Alignment.centerLeft,
                      child: IconButton(
                        icon: Icon(Icons.sort, color: Colors.black),
                        onPressed: () {},
                      ),
                    ),
                    IconButton(
                      icon: Icon(Icons.add_circle, color: Colors.black),
                      onPressed: () async {
                        FilePickerResult pathResult = await FilePicker.platform
                            .pickFiles(
                                type: FileType.audio, allowMultiple: true);
                        for (int i = 0; i < pathResult.paths.length; i  ) {
                          audioPaths.add(pathResult.paths[i]);
                        }
                        print(
                            'AudioPaths Length ============== ${audioPaths.length} ==============');
                        for (int j = 0; j < audioPaths.length; j  ) {
                          await _flutterFFprobe
                              .getMediaInformation(audioPaths[j])
                              .then(
                            (info) {
                              print(
                                  "================Media Information=============");
                              audioTitle.add(
                                  info.getMediaProperties()['tags']['title']);
                              audioAuthor.add(
                                  info.getMediaProperties()['tags']['artist']);
                              audioDuration
                                  .add(info.getMediaProperties()['duration']);
                              print(
                                  '====================> $audioTitle ==============');
                              print(
                                  '====================> $audioAuthor ==============');
                            },
                          );
                        }
                      },
                    ),
                  ],
                ),
              ),
            ),
          ],
        ),
        body: ListView.builder(
            itemCount: audioPaths.length,
            itemBuilder: (BuildContext context, int index) {
              return BookInfoTile(
                  bookCoverImageURL: 'assets/no_cover.png',
                  bookTitle: audioTitle[index],
                  authorName: audioAuthor[index],
                  bookLength: int.parse(audioDuration[index]),
                  onClick: () {
                    print('Button is Clicked');
                  });
            }),
      ),
    );
  }
}
  

Код BookInfoTile :

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

class BookInfoTile extends StatelessWidget {
  final String bookCoverImageURL;
  final String bookTitle;
  final String authorName;
  final int bookLength;
  final onClick;
  final Function onStop;

  const BookInfoTile(
      {Key key,
      @required this.bookCoverImageURL,
      @required this.bookTitle,
      @required this.authorName,
      @required this.bookLength,
      @required this.onClick,
      this.onStop})
      : super(key: key);
  @override
  Widget build(BuildContext context) {
    Size size = MediaQuery.of(context).size;
    return GestureDetector(
      onTap: onClick,
      child: Expanded(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.start,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            ClipRRect(
              borderRadius: BorderRadius.circular(25.0),
              child: Image.asset(
                bookCoverImageURL,
                fit: BoxFit.fill,
                alignment: Alignment.centerLeft,
                height: size.height * 0.22,
                width: size.width * 0.40,
              ),
            ),
            SizedBox(width: 16),
            Expanded(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    bookTitle,
                    overflow: TextOverflow.visible,
                    style: TextStyle(
                      fontWeight: FontWeight.bold,
                      color: Colors.black,
                    ),
                  ),
                  const SizedBox(
                    height: 10,
                  ),
                  Text(
                    'by $authorName',
                    style: TextStyle(
                      fontSize: 15,
                      fontWeight: FontWeight.normal,
                      color: Color(0xFF767676),
                    ),
                  ),
                  const SizedBox(
                    height: 8,
                  ),
                  RichText(
                    text: TextSpan(
                      children: [
                        WidgetSpan(
                          alignment: PlaceholderAlignment.middle,
                          child: SvgPicture.asset(
                            'assets/svg/circle-fill.svg',
                            color: Color(0xFFffe564),
                            height: 10,
                            alignment: Alignment.topCenter,
                          ),
                        ),
                        TextSpan(
                          text: " $bookLength",
                        ),
                      ],
                    ),
                  ),
                  RaisedButton(
                    onPressed: onStop,
                    child: Text('Stop'),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}
  

Ответ №1:

Попробуйте использовать виджет с отслеживанием состояния вместо виджета без состояния. Затем в нажатом fxn кнопки вашего значка окружите код с

setState({

}) ;

Это помогает перестроить listview, и если в audiopath есть содержимое, оно заполнит listview.