Can't convert setState to BloC - flutter

I am developing an audio player application using Flutter, I am using on_audio_query package to get audio files from device storage, and just_audio package for the audio player.
when I created the project, in the audio player I used setState to handle state management, and now, I want to convert to bloc pattern but when I tried to do that I faced a lot of issues and couldn't fix them.
I will attach the code of the audio player and also basic cubit code and if someone guided me or showed me how to convert I would appreciate it.
I'm sorry if the code is confusing but I don't know how to add it correctly.
audio player code
import 'package:just_audio/just_audio.dart';
import 'package:dorosi/shared/ui/my_icon.dart';
import 'package:dorosi/shared/ui/my_text.dart';
import 'package:flutter/material.dart';
import 'package:on_audio_query/on_audio_query.dart';
class AudioPlayerWithUrl extends StatefulWidget {
final SongModel songModel;
const AudioPlayerWithUrl({required this.songModel, Key? key})
: super(key: key);
#override
State<AudioPlayerWithUrl> createState() => _AudioPlayerWithUrlState();
}
class _AudioPlayerWithUrlState extends State<AudioPlayerWithUrl> {
final audioPlayer = AudioPlayer();
bool isPlaying = false;
Duration duration = const Duration();
Duration position = const Duration();
bool isPressed = false;
#override
void initState() {
super.initState();
setAudio();
playAudio();
}
Future setAudio() async {
audioPlayer.setLoopMode(LoopMode.off);
audioPlayer.setAudioSource(
AudioSource.uri(
Uri.parse(widget.songModel.uri!),
),
);
isPlaying = true;
audioPlayer.durationStream.listen((audioDuration) {
setState(() {
duration = audioDuration!;
});
});
audioPlayer.positionStream.listen((audioPosition) {
setState(() {
position = audioPosition;
});
});
}
#override
void dispose() {
audioPlayer.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const MyText(
writtenText: 'Now Playing',
textSize: 23,
textColor: Colors.black,
),
leading: IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: const MyIcon(
icon: Icons.arrow_back,
iconColor: Colors.black,
)),
centerTitle: true,
backgroundColor: Colors.transparent,
elevation: 0,
actions: [
IconButton(
onPressed: () {},
icon: const MyIcon(
icon: Icons.more_vert,
iconColor: Colors.black,
),
),
const SizedBox(width: 10)
],
),
body: SafeArea(
child: SingleChildScrollView(
child: Column(
children: [
const SizedBox(height: 15),
const CircleAvatar(
backgroundColor: Color(0xFFc61104),
radius: 100,
child: MyIcon(
icon: Icons.music_note,
iconSize: 100,
iconColor: Colors.white,
),
),
const SizedBox(
height: 15,
),
const SizedBox(height: 15),
MyText(
writtenText: widget.songModel.title,
textSize: 24,
textWeight: FontWeight.bold,
),
const SizedBox(height: 4),
MyText(
writtenText: widget.songModel.album!,
textSize: 20,
),
const SizedBox(height: 10),
Slider(
activeColor: Colors.orange,
inactiveColor: Colors.black87,
min: 0,
max: duration.inSeconds.toDouble(),
value: position.inSeconds.toDouble(),
onChanged: (value) async {
isPlaying = true;
final position = Duration(seconds: value.toInt());
await audioPlayer.seek(position);
await audioPlayer.play();
}),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
MyText(
writtenText: formatTime(position),
textWeight: FontWeight.bold),
TextButton(
style: TextButton.styleFrom(primary: Colors.black),
onPressed: () {
setState(() {
showRemainingTime();
isPressed = !isPressed;
});
},
child: isPressed
? showRemainingTime()
: MyText(
writtenText: ' ${formatTime(duration)}',
textWeight: FontWeight.bold,
),
),
],
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircleAvatar(
backgroundColor: const Color(0xFFc61104),
radius: 23,
child: IconButton(
onPressed: () async {
if (position >= const Duration(seconds: 10)) {
seekTo(position.inSeconds - 10);
} else {
setState(() {
seekTo(const Duration(seconds: 0).inSeconds);
isPlaying = false;
});
pauseAudio();
}
},
icon: const MyIcon(
icon: Icons.settings_backup_restore,
iconSize: 30,
iconColor: Colors.white,
)),
),
const SizedBox(width: 40),
CircleAvatar(
backgroundColor: const Color(0xFFc61104),
radius: 35,
child: IconButton(
icon: Icon(
isPlaying ? Icons.pause : Icons.play_arrow,
color: Colors.white,
),
iconSize: 50,
onPressed: () {
setState(() {
if (isPlaying) {
pauseAudio();
} else {
playAudio();
}
isPlaying = !isPlaying;
});
},
),
),
const SizedBox(width: 40),
CircleAvatar(
radius: 23,
backgroundColor: const Color(0xFFc61104),
child: IconButton(
onPressed: () async {
if (position < duration - const Duration(seconds: 10)) {
seekTo(position.inSeconds + 10);
} else {
setState(() {
seekTo(duration.inSeconds);
isPlaying = false;
});
pauseAudio();
}
},
icon: const MyIcon(
icon: Icons.forward_10,
iconSize: 30,
iconColor: Colors.white,
)),
),
],
),
const SizedBox(height: 15),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(width: 40),
ElevatedButton(
style: ElevatedButton.styleFrom(primary: Colors.orange),
onPressed: () {
setState(() {
if (audioPlayer.speed == 1) {
adjustAudioSpeed();
debugPrint('${audioPlayer.speed}');
} else if (audioPlayer.speed == 1.25) {
adjustAudioSpeed2();
} else if (audioPlayer.speed == 1.5) {
adjustAudioSpeed3();
} else if (audioPlayer.speed == 1.75) {
adjustAudioSpeed4();
} else if (audioPlayer.speed == 2) {
setAudioNormalSpeed();
}
});
},
child: MyText(
writtenText: '${audioPlayer.speed}',
textSize: 18,
textColor: Colors.black,
)),
const SizedBox(width: 40),
],
)
],
),
)),
);
}
Widget showRemainingTime() {
return MyText(
writtenText: '- ${formatTime(duration - position)}',
textWeight: FontWeight.bold,
);
}
seekTo(int seconds) {
audioPlayer.seek(Duration(seconds: seconds));
}
playAudio() {
audioPlayer.play();
}
pauseAudio() {
audioPlayer.pause();
}
setAudioNormalSpeed() {
audioPlayer.setSpeed(1);
}
adjustAudioSpeed() {
audioPlayer.setSpeed(1.25);
}
adjustAudioSpeed2() {
audioPlayer.setSpeed(1.5);
}
adjustAudioSpeed3() {
audioPlayer.setSpeed(1.75);
}
adjustAudioSpeed4() {
audioPlayer.setSpeed(2);
}
playNextAudio() {
audioPlayer.seekToNext();
}
playPreviousAudio() {
audioPlayer.seekToPrevious();
}
String formatTime(Duration duration) {
String twoDigits(int n) => n.toString().padLeft(2, '0');
final hours = twoDigits(duration.inHours);
final minutes = twoDigits(duration.inMinutes.remainder(60));
final seconds = twoDigits(duration.inSeconds.remainder(60));
return [
if (duration.inHours > 0) hours,
minutes,
seconds,
].join(':');
}
}
player cubit code
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:meta/meta.dart';
part 'player_state.dart';
class PlayerCubit extends Cubit<PlayerState> {
static PlayerCubit get(context) => BlocProvider.of(context);
PlayerCubit() : super(PlayerInitialState());
}
player state code
part of 'player_cubit.dart';
#immutable
abstract class PlayerState {}
class PlayerInitialState extends PlayerState {}
class PlayerPlayingState extends PlayerState {}
class PlayerPauseState extends PlayerState {}

Related

Flutter - Variable in function available when building Widget

If I understood correctly (but clearly I don't) when you need a var available when you build the widget you need to call the function in the initState(). The function is 'void getDevices()'
I need var _documentsIds to build DropdownMenuItem.
var _documentsIds is docs ID from a query I make to FirebaseFirestore
How do I make _documentsIds available to be used in my Widget?
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
import 'package:safegaurd/constants.dart';
import 'package:flutter_time_picker_spinner/flutter_time_picker_spinner.dart';
import 'package:safegaurd/screens/log_in_page.dart';
import 'package:safegaurd/components/buttons_navigate.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'new_device_page.dart';
class DeviceSelectionPage extends StatefulWidget {
const DeviceSelectionPage({Key? key}) : super(key: key);
static const String id = 'device_selection_page';
#override
State<DeviceSelectionPage> createState() => _DeviceSelectionPageState();
}
class _DeviceSelectionPageState extends State<DeviceSelectionPage> {
final _auth = FirebaseAuth.instance;
User? loggedInUser;
final firestoreInstance = FirebaseFirestore.instance;
final String devices = 'devices';
List? _documentsIds;
bool showSpinner = false;
String? selectedValue;
final bool checkOne = false;
Color sDeviceAlways = Colors.white54;
Color sDeviceTime = Colors.white54;
FontWeight sDeviceAlwaysW = FontWeight.normal;
FontWeight sDeviceTimeW = FontWeight.normal;
#override
void initState() {
super.initState();
getCurrentUser();
getDevices();
}
void getCurrentUser() async {
try {
final user = await _auth.currentUser;
if (user != null) {
getDevices();
};
} catch (e) {
print(e);
}
}
void getDevices() async {
var firebaseUser = FirebaseAuth.instance.currentUser?.email;
print('firebaseUser: $firebaseUser');
var query = await firestoreInstance
.collection(devices)
.where('email', isEqualTo: '$firebaseUser')
.get();
var _documentsIds = query.docs.map((doc) => doc.id).toList();
print('_documentsIds: $_documentsIds');
}
#override
Widget build(BuildContext context) {
print('_documentsIds: $_documentsIds');
return Scaffold(
appBar: AppBar(
leading: null,
actions: [
IconButton(
onPressed: () {
_auth.signOut();
Navigator.pop(context);
},
icon: Icon(Icons.close))
],
title: const Text('Device Selection page'),
),
body: ModalProgressHUD(
inAsyncCall: showSpinner,
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(
height: 40,
child: Text(
'SAFEGAURD',
style: kAppTextStyle,
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 380,
padding: const EdgeInsets.symmetric(horizontal: 24.0),
decoration: BoxDecoration(
border: Border.all(
color: Colors.lightBlueAccent, width: 1.0),
borderRadius: kBorderRadius),
child: DropdownButtonHideUnderline(
child: DropdownButton(
hint: const Text(
'Safegaurd Devices',
style: TextStyle(color: Colors.white54, fontSize: 25),
),
style:
const TextStyle(color: Colors.orange, fontSize: 25),
borderRadius: kBorderRadius,
iconSize: 40,
elevation: 16,
onChanged: (value) {
setState(() {
selectedValue = value.toString();
setState(() {
selectedValue;
print(selectedValue);
});
});
},
value: selectedValue,
items: _documentsIds?.map((itemsList) {
return DropdownMenuItem<String>(
value: itemsList,
child: Text(itemsList),
);
}).toList(),
),
),
)
],
),
Row(
children: [
Buttons_Navigate(
colour: Colors.teal,
title: 'Save Settings',
onPressed: () {},
width: 200,
),
],
),
Row(
children: [
Buttons_Navigate(
colour: Colors.teal,
title: 'Claim new Device',
onPressed: () {
Navigator.pushNamed(context, NewDevicePage.id);
},
width: 200,
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Buttons_Navigate(
colour: Colors.orange,
title: 'Back',
onPressed: () {
Navigator.pushNamed(context, LogInPage.id);
},
width: 40)
],
)
],
)),
));
}
}
wall, you can use futureBuilder and show A CircularProgressBar until the query is done check the documentation here: FutureBuilder
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
import 'package:safegaurd/constants.dart';
//import 'package:flutter_time_picker_spinner/flutter_time_picker_spinner.dart';
import 'package:safegaurd/screens/log_in_page.dart';
import 'package:safegaurd/components/buttons_navigate.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'new_device_page.dart';
class DeviceSelectionPage extends StatefulWidget {
const DeviceSelectionPage({Key? key}) : super(key: key);
static const String id = 'device_selection_page';
#override
State<DeviceSelectionPage> createState() => _DeviceSelectionPageState();
}
class _DeviceSelectionPageState extends State<DeviceSelectionPage> {
final _auth = FirebaseAuth.instance;
User? loggedInUser;
final firestoreInstance = FirebaseFirestore.instance;
final String devices = 'devices';
List? _documentsIds;
bool showSpinner = false;
//bool _isSelected1 = false;
//bool _isSelected2 = false;
//DateTime _dateTime = DateTime.now();
String? selectedValue;
final bool checkOne = false;
Color sDeviceAlways = Colors.white54;
Color sDeviceTime = Colors.white54;
FontWeight sDeviceAlwaysW = FontWeight.normal;
FontWeight sDeviceTimeW = FontWeight.normal;
#override
void initState() {
super.initState();
getCurrentUser();
getDevices();
}
void getCurrentUser() async {
try {
final user = await _auth.currentUser;
if (user != null) {
getDevices();
};
} catch (e) {
print(e);
}
}
Future<List<dynamic>> getDevices() async {
var firebaseUser = FirebaseAuth.instance.currentUser?.email;
print('firebaseUser: $firebaseUser');
var query = await firestoreInstance
.collection(devices)
.where('email', isEqualTo: '$firebaseUser')
.get();
List<String> _documentsIds = query.docs.map((doc) => doc.id).toList();
print('_documentsIds: $_documentsIds');
return _documentsIds;
}
#override
Widget build(BuildContext context) {
print('_documentsIds: $_documentsIds');
return Scaffold(
appBar: AppBar(
leading: null,
actions: [
IconButton(
onPressed: () {
_auth.signOut();
Navigator.pop(context);
},
icon: Icon(Icons.close))
],
title: const Text('Device Selection page'),
),
body: ModalProgressHUD(
inAsyncCall: showSpinner,
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(
height: 40,
child: Text(
'SAFEGAURD',
style: kAppTextStyle,
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 380,
padding: const EdgeInsets.symmetric(horizontal: 24.0),
decoration: BoxDecoration(
border: Border.all(
color: Colors.lightBlueAccent, width: 1.0),
borderRadius: kBorderRadius),
child: DropdownButtonHideUnderline(
child: FutureBuilder<List> (
future: getDevices(),
builder: (BuildContext context, AsyncSnapshot<List> snapshot){
if (!snapshot.hasData) {
return const Text('Waiting Devices',style: TextStyle(color: Colors.white54, fontSize: 25));
} else {
return DropdownButton(
hint: const Text(
'Safegaurd Devices',
style: TextStyle(color: Colors.white54, fontSize: 25),
),
style:
const TextStyle(color: Colors.orange, fontSize: 25),
borderRadius: kBorderRadius,
iconSize: 40,
elevation: 16,
onChanged: (value) {
setState(() {
selectedValue = value.toString();
setState(() {
selectedValue;
print(selectedValue);
});
});
},
value: selectedValue,
items: snapshot.data?.map((_documentsIds) =>
DropdownMenuItem<String>(
value: _documentsIds,
child: Text(_documentsIds),
)
).toList(),
);
}
}
)
),
)
],
),
Row(
children: [
Buttons_Navigate(
colour: Colors.teal,
title: 'Save Settings',
onPressed: () {},
width: 200,
),
],
),
Row(
children: [
Buttons_Navigate(
colour: Colors.teal,
title: 'Claim new Device',
onPressed: () {
Navigator.pushNamed(context, NewDevicePage.id);
},
width: 200,
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Buttons_Navigate(
colour: Colors.orange,
title: 'Back',
onPressed: () {
Navigator.pushNamed(context, LogInPage.id);
},
width: 40)
],
)
],
)),
));
}

tcard is not resetting, getting null in tcardController.state Flutter

I am tcard pkg in my project. i want reset the card in every 5 seconds automatically the length of the list is changing but the UI is not resetting, getting null in tcardController.state
Is there any other pkg, so we can achieve same functionality of this tcard pkg.
Refer to below code:-
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:tcard/tcard.dart';
List<Color> colors = [
Colors.blue,
Colors.yellow,
Colors.red,
Colors.orange,
Colors.pink,
Colors.amber,
Colors.cyan,
Colors.purple,
Colors.brown,
Colors.teal,
];
class TCardPage extends StatefulWidget {
const TCardPage({Key? key}) : super(key: key);
#override
_TCardPageState createState() => _TCardPageState();
}
class _TCardPageState extends State<TCardPage> {
final TCardController _controller = TCardController();
int _index = 0;
Timer? timer;
bool changeColor = false;
#override
void initState() {
super.initState();
timer = Timer.periodic(
const Duration(seconds: 5), (Timer t) => sequenceApiCall());
print(_controller.state.toString());
// _controller.reset;
}
void sequenceApiCall() {
changeColor = !changeColor;
Future.delayed(const Duration(seconds: 10), () {
print('sequenceApiCall');
if (changeColor) {
print('changeColor');
colors.removeAt(0);
print('color count = ${colors.length}'); //9
} else {
colors.insert(0, Colors.black);
print('black');
print('color count = ${colors.length}'); //10
}
print(_controller.state.toString());
_controller.reset();
setState(() {});
});
}
#override
void dispose() {
super.dispose();
timer?.cancel();
_controller.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
children: <Widget>[
const SizedBox(height: 200),
TCard(
cards: cardsColor,
controller: _controller,
onForward: (index, info) {
_index = index;
print(info.direction);
setState(() {});
},
onBack: (index, info) {
_index = index;
setState(() {});
},
onEnd: () {
print('end');
},
),
SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
OutlineButton(
onPressed: () {
_controller.back();
},
child: const Text('Back'),
),
OutlineButton(
onPressed: () {
_controller.forward();
},
child: const Text('Forward'),
),
OutlineButton(
onPressed: () {
_controller.reset();
},
child: const Text('Reset'),
),
],
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: Text(_index.toString()),
),
);
}
List<Widget> cardsColor = List.generate(
colors.length,
(int index) {
return Container(
alignment: Alignment.center,
decoration: BoxDecoration(
color: colors[index],
),
child: Text(
'${index + 1}',
style: const TextStyle(fontSize: 100.0, color: Colors.white),
),
);
},
);
}
Thanks in advance.!!!

How can i stop playing audio in Flutter

I am using audioplayers: ^0.18.0 for playing audio when the screen appears.
This is code for playing audio which is called in initstate:
void initState() {
startTimer();
playLocalAsset();
super.initState();
}
This is to call the play function:
AudioPlayer player;
Future<AudioPlayer> playLocalAsset() async {
AudioCache cache = new AudioCache();
//At the next line, DO NOT pass the entire reference such as assets/yes.mp3. This will not work.
//Just pass the file name only.
return await cache.play("audio.wav");
}
I want to stop it inside onPressed():
onPressed: () {
// this is where stop audio should be used
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return Homepage(
device: widget.device,
);
},
),
);
},
How can I stop the audio sound when I press the button of Cancel which I have made in my flutter app. I cannot call it as Future to stop it, kindly help me out.
Nabia Salman
I made an audio player 1 year ago. I did not really know what i was doing. I just tried to do something.
I copied my code here. I hope it could help you.
You can use this code freely. This code is made before Flutter 2.2, so it can be some error due to the null safety.
class _SongsPage extends State<SongsPage> {
List<String> pictures = <String>["assets/images/thespectre.jpg", "assets/images/home.jpg", "assets/images/alone.jpg", "assets/images/lostf.jpg", "assets/images/breakingme.png", "assets/images/cry.jpg", "assets/images/onelife.jpg", "assets/images/coming.jpg", "assets/images/allnight.jpg", "assets/images/wildest.jpg", "assets/images/lovers.jpg", "assets/images/nothing.jpg"];
List<String> songname = <String>["The Spectre", "Home", "Alone", "Don't Leave Me Now", "Breaking Me", "Cry", "One Life", "Coming Home", "All Night", "Wildest Dream", "Lovers For The Weekend", "Nothing Stopping Me"];
List<String> performer = <String>["Alan Walker", "Martin Garrix", "Marshmello", "Lost Frequencies", "Topic", "Gryffin", "Mike Perry", "Dimitri Vangelis & Wyman", "Afrojack", "Thomas Gold", "John De Sohn", "Vicetone"];
List<String> song = <String>['TheSpectre.mp3', 'Home.mp3', 'Alone.mp3', 'DontLeaveMeNow.mp3', 'BreakingMe.mp3', 'Cry.mp3', 'OneLife.mp3', 'ComingHome.mp3', 'AllNight.mp3', 'WildestDream.mp3', 'LoversForTheWeekend.mp3', 'NothingStoppingMe.mp3'];
bool isPlaying = false;
bool isLiked = false;
int index = 0;
Duration _duration = new Duration();
Duration _position = new Duration();
AudioPlayer advancedPlayer;
AudioCache audioCache;
_SongsPage(int indexer){
index = indexer;
}
#override
void initState() {
super.initState();
initPlayer();
}
void initPlayer() {
advancedPlayer = new AudioPlayer();
audioCache = new AudioCache(fixedPlayer: advancedPlayer);
advancedPlayer.durationHandler = (d) => setState(() {
_duration = d;
});
advancedPlayer.positionHandler = (p) => setState(() {
_position = p;
});
}
String localFilePath;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [kbackgroundcolorpink, kbackgroundcolorblue],
tileMode: TileMode.repeated,
),
),
child: Column(
children: <Widget>[
Expanded(
flex: 10,
child: Column(
children: <Widget>[
//Picture
Container(
margin: EdgeInsets.only(top: 120),
width: 200,
height: 200,
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: kblack.withOpacity(0.4),
spreadRadius: 3,
blurRadius: 4,
offset: Offset(3, 2),
),
],
),
child: Image.asset(pictures[index]),
),
//Song and Performer
Container(
margin: EdgeInsets.only(top: 20),
height: 80,
child: Column(
children: <Widget>[
Text(songname[index], style: kheadlinesong),
Text(performer[index], style: kheadlineperformer),
],
),
),
//Timer
Container(
padding: EdgeInsets.only(right: 36),
child: Align(
alignment: Alignment.centerRight,
child: Text((_position.inMinutes).toString() + ":" + (_position.inSeconds - (_position.inMinutes * 60)).toString().padLeft(2, "0") + " / " + (_duration.inMinutes).toString() + ":" + (_duration.inSeconds - (_duration.inMinutes * 60)).toString().padLeft(2, "0"), textAlign: TextAlign.right, style: kheadlineperformer),
),
),
//Line
Container(
padding: EdgeInsets.only(right: 12, left: 12),
child: Slider(
activeColor: kbackgroundcolorpink,
inactiveColor: kbackgroundcolorblue,
value: _position.inSeconds.toDouble(),
min: 0.0,
max: _duration.inSeconds.toDouble(),
onChanged: (double value) {
setState(() {
seekToSecond(value.toInt());
value = value;
});
}),
),
],
),
),
Expanded(
flex: 3,
child: Container(
child: Column(
children: <Widget>[
Container(
padding: EdgeInsets.only(bottom: 15),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Spacer(),
Spacer(),
IconButton(
icon: PreviousIcon,
onPressed: () {PreviousIconClick();},
),
Spacer(),
IconButton(
icon: Icon(isPlaying ? PauseIcon : PlayIcon2, color: kwhite, size: 40),
onPressed: () {PausePlayIconClick();},
),
Spacer(),
IconButton(
icon: NextIcon,
onPressed: () {NextIconClick();},
),
Spacer(),
Spacer(),
],
),
),
Container(
padding: EdgeInsets.only(top: 15),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Spacer(),
IconButton(
icon: Icon(isLiked ? LikeIcon2 : LikeIcon, color: kwhite, size: 26),
onPressed: () {LikeIconClick();},
),
Spacer(),
IconButton(
icon: ShareIcon,
onPressed: () {ShareIconClick();},
),
Spacer(),
IconButton(
icon: Icon(ReplayIcon, color: isPlaying ? kbackgroundcolorpink : kwhite, size: 26),
onPressed: () {ReplayIconClick();},
),
Spacer(),
IconButton(
icon: AddToListIcon,
onPressed: () {AddIconClick();},
),
Spacer(),
],
),
),
],
),
),
),
],
),
),
);
}
void seekToSecond(int second) {
Duration newDuration = Duration(seconds: second);
advancedPlayer.seek(newDuration);
}
void PreviousIconClick(){
if(index == 0){
index = index;
Playing();
}
else {
index--;
Playing();
}
}
void NextIconClick(){
if (index == song.length - 1){
index = 0;
Playing();
}
else{
index++;
Playing();
}
}
void LikeIconClick(){
if(isLiked){
setState(() {
isLiked = false;
});
}
else{
setState(() {
isLiked = true;
});
}
}
void ReplayIconClick(){
}
void AddIconClick(){
}
void ShareIconClick(){
}
void Playing(){
audioCache.play(song[index]);
setState(() {
isPlaying = true;
});
}
void PausePlayIconClick(){
if(isPlaying){
advancedPlayer.pause();
setState(() {
isPlaying = false;
});
}
else{
audioCache.play(song[index]);
setState(() {
isPlaying = true;
});
}
}
}
And this is look like this, and works fine.
I have answered my own question
Initializing the function for play and stop
AudioPlayer player = new AudioPlayer();
AudioCache audioCache;
String mp3Uri = "audio.wav";
void _playSound() {
audioCache = new AudioCache(fixedPlayer: player);
audioCache.play("audio.wav");
}
void _stopSound() {
player.stop();
}
Now call _playSound function inside initState and inside onPressed call _stopSound function
Please try this flutter package audioplayers
assets:
- assets/icons/
- ringtone.mp3
- ringer.mp3
- miss_call.mp3
import 'dart:io';
import 'package:audioplayers/audio_cache.dart';
import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/material.dart';
AudioPlayer advancedPlayer = AudioPlayer();
AudioCache audioCache = AudioCache();
class PlayAudioTone{
playRingTone() {
audioCache.getAbsoluteUrl('ringtone.mp3').then((value) {
print(value);
final file = new File(value);
advancedPlayer.play(file.path, isLocal: true,);
});
}
stopRingTone(){
advancedPlayer.stop();
}
playRinger() {
audioCache.getAbsoluteUrl('ringer.mp3').then((value) {
print(value);
final file = new File(value);
advancedPlayer.play(file.path, isLocal: true);
// advancedPlayer.setVolume(0.01);
});
}
stopRinger(){
advancedPlayer.stop();
}
}

How to pass speech to text field in flutter?

I have an application in Flutter that translates speech to text, the problem is that I have not found a way to put the results in input or a TextField in Flutter, so far it only transcribes to text which cannot (obviously) be modified. How to put the results in a TextField?
This is my code:
import 'package:flutter/material.dart';
import 'package:speech_to_text/speech_to_text.dart' as stt;
class SpeechScreen extends StatefulWidget {
#override
_SpeechScreenState createState() => _SpeechScreenState();
}
class _SpeechScreenState extends State<SpeechScreen> {
stt.SpeechToText _speech;
bool _isListening = false;
String _textSpeech = 'Presiona el botón para iniciar a hablar';
void onListen() async {
bool available = await _speech.initialize(
onStatus: (val) => print('onStatus: $val'),
onError: (val) => print('onError: $val'));
if (!_isListening) {
if (available) {
setState(() {
_isListening = false;
_speech.listen(
onResult: (val) => setState(() {
_textSpeech = val.recognizedWords;
}),
);
});
}
} else {
setState(() {
_isListening = false;
_speech.stop();
});
}
}
void stopListen() {
_speech.stop();
setState(() {});
}
#override
void initState() {
super.initState();
_speech = stt.SpeechToText();
}
#override
Widget build(BuildContext context) {
_fondoApp() {
final gradiente = Container(
width: double.infinity,
height: double.infinity,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: FractionalOffset(0.0, 0.0),
end: FractionalOffset(0.0, 1.0),
colors: [Colors.black87, Colors.black])),
);
return Stack(
children: <Widget>[gradiente],
);
}
return Scaffold(
body: Stack(children: <Widget>[
_fondoApp(),
Container(
padding: EdgeInsets.all(30.0),
child: Text(_textSpeech,
style: TextStyle(
fontSize: 32,
color: Colors.white,
fontWeight: FontWeight.w500))),
]),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
floatingActionButton: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FloatingActionButton(
onPressed: onListen,
child: Icon(Icons.mic),
backgroundColor: Colors.green,
),
SizedBox(
width: 40,
),
SizedBox(
child: _speech.isListening
? Text(
"Escuchando...",
style: TextStyle(
color: Colors.white, fontWeight: FontWeight.bold),
)
: Text(
'Sin escuchar',
style: TextStyle(
color: Colors.white, fontWeight: FontWeight.bold),
),
),
SizedBox(
width: 40,
),
FloatingActionButton(
child: Icon(Icons.stop),
heroTag: "btn2",
backgroundColor: Colors.redAccent,
onPressed: () => stopListen(),
),
],
),
));
}
}
Your help would really be amazing, thank you.
We can create a TextField with a TextEditingController:
class _SpeechScreenState extends State<SpeechScreen> {
TextEditingControlller _textEditingController = TextEditingControlller();
Widget _buildTextController() {
return TextField(controller: _textEditingController);
}
}
By doing so, after we translate the speech to text, we can update the _textEditingController text:
void onListen() async {
bool available = await _speech.initialize(
onStatus: (val) => print('onStatus: $val'),
onError: (val) => print('onError: $val'));
if (!_isListening) {
if (available) {
setState(() {
_isListening = false;
_speech.listen(
onResult: (val) => setState(() {
_textSpeech = val.recognizedWords;
_textEditingController.text = val.recognizedWords;
}),
);
});
}
} else {
setState(() {
_isListening = false;
_speech.stop();
});
}
}

How to save page state on revisit in flutter

I have 2 screens and I am trying to achieve understand how to achieve page state. For example, in the below screen, I have 4 options, and all of them take the user to the same screen the only difference is API getting called for each of them is different to build a list. I am trying to handle back arrow action, and that's where I am having issues.
Use Case -
When user is on screen 2 he is playing the song, now on back press song continues to play. Now when the user again chooses the same option from screen 1 I want to show the same list without reload and selection. If user selects any other option it should behave normal, which is working.
Solution -
I can hardcode loaded songs list and send back to screen 1 and then again get that back with the selection but this will take lot of resources.
AutomaticKeepAliveClientMixin i tried this tutorial but that didn't help or kept state active.
PageStorage is 3rd option i saw but i found majority of the time this is being used on app where we have a tab.
Screen 1 -
class Dashboard extends StatefulWidget {
int playingId;
Dashboard({this.playingId});
#override
_DashboardState createState() => _DashboardState(playingId);
}
class _DashboardState extends State<Dashboard> {
String appname;
int playingId = 0;
_DashboardState(this.playingId);
// print('${playingId}');
#override
void initState() {
appname="";
// playingId=0;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0,
backgroundColor: AppColors.darkBlue,
centerTitle: true,
title: Text("Tirthankar",
style: TextStyle(color: Colors.white),),
),
backgroundColor: AppColors.styleColor,
body: Column(
children: <Widget>[
// SizedBox(height: 5),
Padding(
padding: const EdgeInsets.all(20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
CustomGridWidget(
child: Icon(
Icons.file_download,
size: 100,
color: AppColors.styleColor,
),
// image: 'assets/bhaktambar.png',
sizew: MediaQuery.of(context).size.width * .4,
sizeh: MediaQuery.of(context).size.width * .5,
borderWidth: 2,
label: "Bhakti",
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => ListPage(appname: "Kids",playingId: playingId,),
),
);
},
),
CustomGridWidget(
child: Icon(
Icons.file_download,
size: 100,
color: AppColors.styleColor,
),
// image: 'assets/bhaktambar.png',
sizew: MediaQuery.of(context).size.width * .4,
sizeh: MediaQuery.of(context).size.width * .5,
borderWidth: 2,
label: "Kids",
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => ListPage(appname: "Kids",playingId: playingId,),
),
);
},
),
],
),
),
Padding(
padding: const EdgeInsets.only(
left: 20,
right: 20,
bottom: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
CustomGridWidget(
child: Icon(
Icons.favorite,
size: 100,
color: AppColors.styleColor,
),
// image: 'assets/kids.jpg',
sizew: MediaQuery.of(context).size.width * .4,
sizeh: MediaQuery.of(context).size.width * .5,
borderWidth: 2,
label: "Favorite",
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => ListPage(appname: "Songs"),
),
);
},
),
Align(
alignment: Alignment.center,
child: CustomGridWidget(
child: Icon(
Icons.book,
size: 100,
color: AppColors.styleColor,
),
// image: 'assets/vidyasagar.jpg',
sizew: MediaQuery.of(context).size.width * .4,
sizeh: MediaQuery.of(context).size.width * .5,
borderWidth: 2,
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => ListPage(appname: "Bhajan"),
),
);
},
),
),
],
),
),
]
),
);
}
Material boxTiles(IconData icon, String name){
return Material(
color: AppColors.mainColor,
elevation: 14.0,
shadowColor: AppColors.styleColor,
borderRadius: BorderRadius.circular(24.0),
child: Center(
child: Padding(
padding: const EdgeInsets.all(8.0),
child:Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
InkWell(
onTap: (){print("tapped"); /* or any action you want */ },
child: Container(
width: 130.0,
height: 10.0,
color : Colors.transparent,
), // container
), //
//Text
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(name,
style:TextStyle(
color: AppColors.styleColor,
fontSize: 20.0,
)
),
),
//Icon
Material(
color: AppColors.styleColor,
borderRadius: BorderRadius.circular(50.0),
child: Padding(padding: const EdgeInsets.all(10.0),
child: Icon(icon, color: AppColors.lightBlue,size: 30,),
),
),
],
)
],
)
),
)
);
}
}
Screen 2 -
// import 'dart:js';
class ListPage extends StatefulWidget {
String appname;
int playingId;
ListPage({this.appname,this.playingId});
#override
_ListPageState createState() => _ListPageState(appname,playingId);
}
class _ListPageState extends State<ListPage>
with SingleTickerProviderStateMixin,AutomaticKeepAliveClientMixin<ListPage> {
String appname;
int playingId;
bool isPlaying = false;
_ListPageState(this.appname,playingId);
// List<MusicModel> _list1;
List<MusicData> _list;
var _value;
int _playId;
int _songId;
String _playURL;
bool _isRepeat;
bool _isShuffle;
bool _isFavorite;
String _startTime;
String _endTime;
AnimationController _controller;
Duration _duration = new Duration();
Duration _position = new Duration();
final _random = new Random();
AudioPlayer _audioPlayer = AudioPlayer();
#override
void initState() {
_playId = 0;
// _list1 = MusicModel.list;
this._fileUpdate();
// _list = _list1;
_controller =
AnimationController(vsync: this, duration: Duration(microseconds: 250));
_value = 0.0;
_startTime = "0.0";
_endTime = "0.0";
_isRepeat = false;
_isShuffle = false;
_isFavorite = false;
_audioPlayer.onAudioPositionChanged.listen((Duration duration) {
setState(() {
// _startTime = duration.toString().split(".")[0];
_startTime = duration.toString().split(".")[0];
_duration = duration;
// _position = duration.toString().split(".")[0];
});
});
_audioPlayer.onDurationChanged.listen((Duration duration) {
setState(() {
_endTime = duration.toString().split(".")[0];
_position = duration;
});
});
_audioPlayer.onPlayerCompletion.listen((event) {
setState(() {
isPlaying = false;
_position = _duration;
if (_isRepeat) {
_songId = _songId;
} else {
if (_isShuffle) {
var element = _list[_random.nextInt(_list.length)];
_songId = element.id;
} else {
_songId = _songId + 1;
}
}
_player(_songId);
});
});
super.initState();
}
bool get wantKeepAlive => true;
#override
Widget build(BuildContext context) {
super.build(context);
return Scaffold(
appBar: AppBar(
elevation: 0,
backgroundColor: AppColors.mainColor,
centerTitle: true,
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: (){
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => Dashboard(playingId: _songId),
),
);
},
),
title: Text(
appname,
style: TextStyle(color: AppColors.styleColor),
),
),
backgroundColor: AppColors.mainColor,
body: Stack(
children: <Widget>[
Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(24.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
CustomButtonWidget(
child: Icon(
Icons.favorite,
color: AppColors.styleColor,
),
size: 50,
onTap: () {},
),
CustomButtonWidget(
image: 'assets/logo.jpg',
size: 100,
borderWidth: 5,
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => DetailPage(),
),
);
},
),
CustomButtonWidget(
child: Icon(
Icons.menu,
color: AppColors.styleColor,
),
size: 50,
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => HomePage(),
),
);
},
)
],
),
),
slider(),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 15),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(
icon: Icon(
_isRepeat ? Icons.repeat_one : Icons.repeat,
color: _isRepeat ? Colors.brown : AppColors.styleColor,
),
onPressed: () {
if (_isRepeat) {
_isRepeat = false;
} else {
_isRepeat = true;
}
},
),
IconButton(
icon: Icon(
isPlaying ? Icons.pause : Icons.play_arrow,
color: AppColors.styleColor,
),
onPressed: () {
if (isPlaying) {
_audioPlayer.pause();
setState(() {
isPlaying = false;
});
} else {
if (!isPlaying){
_audioPlayer.resume();
setState(() {
isPlaying = true;
});
}
}
}),
IconButton(
icon: Icon(
Icons.stop,
color: AppColors.styleColor,
),
onPressed: () {
if (isPlaying){
_audioPlayer.stop();
setState(() {
isPlaying = false;
_duration = new Duration();
});
}
// isPlaying = false;
}),
IconButton(
icon: Icon(
Icons.shuffle,
color:
_isShuffle ? Colors.brown : AppColors.styleColor,
),
onPressed: () {
if (_isShuffle) {
_isShuffle = false;
} else {
_isShuffle = true;
}
}),
],
),
),
Expanded(
//This is added so we can see overlay else this will be over button
child: ListView.builder(
physics:
BouncingScrollPhysics(), //This line removes the dark flash when you are at the begining or end of list menu. Just uncomment for
// itemCount: _list.length,
itemCount: _list == null ? 0 : _list.length,
padding: EdgeInsets.all(12),
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
_songId = index;
_player(index);
},
child: AnimatedContainer(
duration: Duration(milliseconds: 500),
//This below code will change the color of sected area or song being played.
decoration: BoxDecoration(
color: _list[index].id == _playId
? AppColors.activeColor
: AppColors.mainColor,
borderRadius: BorderRadius.all(
Radius.circular(20),
),
),
//End of row color change
child: Padding(
padding: const EdgeInsets.all(
16), //This will all padding around all size
child: Row(
mainAxisAlignment: MainAxisAlignment
.spaceBetween, //This will allign button to left, else button will be infront of name
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
_list[index].title,
style: TextStyle(
color: AppColors.styleColor,
fontSize: 16,
),
),
Text(
_list[index].album,
style: TextStyle(
color: AppColors.styleColor.withAlpha(90),
fontSize: 16,
),
),
],
),
IconButton(
icon: Icon(_isFavorite
? Icons.favorite
: Icons.favorite_border),
onPressed: () {
if (_isFavorite) {
_isFavorite = false;
} else {
_isFavorite = true;
}
})
//Diabled Play button and added fav button.
// CustomButtonWidget(
// //This is Play button functionality on list page.
// child: Icon(
// _list[index].id == _playId
// ? Icons.pause
// : Icons.play_arrow,
// color: _list[index].id == _playId
// ? Colors.white
// : AppColors.styleColor,
// ),
// size: 50,
// isActive: _list[index].id == _playId,
// onTap: () async {
// _songId = index;
// _player(index);
// },
// )
],
),
),
),
);
},
),
)
],
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
height: 50,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
AppColors.mainColor.withAlpha(0),
AppColors.mainColor,
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
)),
),
)
],
),
// floatingActionButton: FloatingActionButton(
// child: Icon(Icons.music_note),
// onPressed: () async { // String filePath = await FilePicker.getFilePath();
// int status = await _audioPlayer.play("https://traffic.libsyn.com/voicebot/Jan_Konig_on_the_Jovo_Open_Source_Framework_for_Voice_App_Development_-_Voicebot_Podcast_Ep_56.mp3");
// if (status == 1){
// setState(() {
// isPlaying = true;
// });
// }
// },
// )
);
}
Widget slider() {
return Slider(
activeColor: AppColors.styleColor,
inactiveColor: Colors.lightBlue,
value: _duration.inSeconds.toDouble(),
min: 0.0,
max: _position.inSeconds.toDouble(),
divisions: 10,
onChangeStart: (double value) {
print('Start value is ' + value.toString());
},
onChangeEnd: (double value) {
print('Finish value is ' + value.toString());
},
onChanged: (double value) {
setState(() {
seekToSecond(value.toInt());
value = value;
});
});
}
Future<Void> _fileUpdate() async {
String url =
"azonaws.com/input.json";
String arrayObjsText = "";
try {
eos.Response response;
Dio dio = new Dio();
response = await dio.get(url,options: Options(
responseType: ResponseType.plain,
),);
arrayObjsText = response.data;
print(response.data.toString());
} catch (e) {
print(e);
}
var tagObjsJson = jsonDecode(arrayObjsText)['tags'] as List;
this.setState(() {
_list = tagObjsJson.map((tagJson) => MusicData.fromJson(tagJson)).toList();
});
// return _list;
// print(_list);
}
Future<void> _player(int index) async {
if (isPlaying) {
if (_playId == _list[index].id) {
int status = await _audioPlayer.pause();
if (status == 1) {
setState(() {
isPlaying = false;
});
}
} else {
_playId = _list[index].id;
_playURL = _list[index].songURL;
_audioPlayer.stop();
int status = await _audioPlayer.play(_playURL);
if (status == 1) {
setState(() {
isPlaying = true;
});
}
}
} else {
_playId = _list[index].id;
_playURL = _list[index].songURL;
int status = await _audioPlayer.play(_playURL);
if (status == 1) {
setState(() {
isPlaying = true;
});
}
}
}
String _printDuration(Duration duration) {
String twoDigits(int n) {
if (n >= 10) return "$n";
return "0$n";
}
String twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60));
String twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60));
return "${twoDigits(duration.inHours)}:$twoDigitMinutes:$twoDigitSeconds";
}
void seekToSecond(int second) {
Duration newDuration = Duration(seconds: second);
_audioPlayer.seek(newDuration);
}
}
PageStorage is 3rd option i saw but i found majority of the time this is being used on app where we have a tab.
You still can use this approach with what you want, with or without Tab/ bottom navigation bar.
PageViewClass
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> with SingleTickerProviderStateMixin{
PageController _pageController;
#override
void initState() {
super.initState();
_pageController = PageController();
}
#override
void dispose() {
super.dispose();
_pageController?.dispose();
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: PageView(
controller: _pageController,
physics: NeverScrollableScrollPhysics(), // so the user cannot scroll, only animating when they select an option
children: <Widget>[
Dashboard(playingId: 1, key: PageStorageKey<String>('MyPlayList'), pageController: _pageController), //or the name you want, but you need to give them a key to all the child so it can save the Scroll Position
ListPage(appname: "FirstButton",playingId: 1, key: PageStorageKey<String>('FirstButton'), pageController: _pageController),
ListPage(appname: "SecondButton",playingId: 1, key: PageStorageKey<String>('SecondButton'), pageController: _pageController),
ListPage(appname: "ThirdButton",playingId: 1, key: PageStorageKey<String>('ThirdButton'), pageController: _pageController),
ListPage(appname: "FourthButton",playingId: 1, key: PageStorageKey<String>('FourthButton'), pageController: _pageController)
],
),
)
);
}
}
Now you pass the PageController to all children (add a key and PageController attribute to Screen 1 and 2) and in DashBoard (Screen 1) you can change the onTap of the buttons from the MaterialRoute to this
onTap: () => widget.pageController.jumpToPage(x), //where x is the index of the children of the PageView you want to see (between 0 and 4 in this case)
In Screen 2 you wrap all your Scaffold with a WillPopScope so when the user tap back instead of closing the route it goes back to the Dashboard Widget at index 0
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () {
widget.pageController.jumpToPage(0); // Move back to dashboard (index 0)
return false;
}
child: Scaffold(...)
);
}
You can use other methods of PageController if you want some effects like animations (animateTo, nextPage, previousPage, etc.)