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