Hello any flutter experts is here who can help solving little issue i want implement flutter voice recognition. flutter speech_to_text: ^5.4.3. plugin which is work fine but problem is that i want implement like native voice recognition on top bar when user click on mic button its appears alert dialog showing in picture below and when user speak its shows text like image below anyone know about here is picture clicke on it
i also used custom dialog builder for this purpose but my text is not update in dialoge text check code below
import 'dart:math';
import 'package:bibleapp/Dbhelper.dart';
import 'package:bibleapp/chapters.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:speech_to_text/speech_recognition_result.dart';
import 'package:speech_to_text/speech_to_text.dart' as stt;
import 'package:speech_to_text/speech_to_text.dart';
import 'package:avatar_glow/avatar_glow.dart';
class Booknames extends StatefulWidget {
const Booknames({Key? key}) : super(key: key);
@override
_BooknamesState createState() => _BooknamesState();
}
class _BooknamesState extends State<Booknames> {
var booknames=['Genesis','Exodus','Leviticus','Numbers',
'Deuteronomy','Joshua',
'Judges','Ruth','1 Samuel','2 Samuel','1 Kings','2 Kings',
'1 Chronicles','2 Chronicles','Ezra','Nehemiah','Esther',
'Job','Psalms','Proverbs','Ecclesiastes','Song of Solomon','Isaiah','Jeremiah',
'Lamentations','Ezekiel','Daniel','Hosea','Joel','Amos','Obadiah','Jonah','Micah',
'Nahum','Habakkuk','Zephaniah','Haggai','Zechariah','Malachi','Matthew',
'Mark','Luke','John','Acts','Romans','1 Corinthians','2 Corinthians','Galatians',
'Ephesians','Philippians','Colossians','1 Thessalonians','2 Thessalonians','1 Timothy',
'2 Timothy','Titus','Philemon','Hebrews','James','1 Peter',
'2 Peter','1 John','2 John','3 John','Jude','Revelation'];
Dbhelper dbhelper=new Dbhelper();
stt.SpeechToText speechToText=stt.SpeechToText();
bool islistening=false;
//this text i want change after listening
String text='Example:Gensis Chapter 1 verse 5';
@override
void initState() {
// TODO: implement initState
super.initState();
dbhelper.db;
_initSpeech();
}
/// This has to happen only once per app
void _initSpeech() async {
speechToText.initialize();
}
///this dialog when user press on mic button it show alert alert dialog button
showAlertDialog() {
Widget okButton = TextButton(
child: Text("CANCEL VOICE"),
onPressed: () => Navigator.of(context).pop(false),
);
AlertDialog alert = AlertDialog(
title: Text("Search by voice"),
content: Container(
height: 180,
child: Column(
children: [
AvatarGlow(
glowColor: Colors.blue,
endRadius: 75,
duration: Duration(milliseconds: 2500),
repeat: true,
showTwoGlows: islistening,
repeatPauseDuration: Duration(milliseconds: 150),
child: Material(
elevation: 5,
shape: CircleBorder(),
child: CircleAvatar(
backgroundColor: Colors.white,
child: Icon(Icons.mic, color: Colors.blue, size: 30,),
radius: 50,
),
),
),
Expanded(child: Container(
child: Text(text),
)),
],
),
),
actions: [
okButton,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: <Widget>[
new IconButton(
///when user clickec on mic button dialog and speech rcoginition methods calll
icon: new Icon(islistening?Icons.mic:Icons.mic_none),
highlightColor: Colors.pink,
onPressed:(){
setState(() {
showAlertDialog();
_listen();
});
},
),
],
elevation: 0,
title: Text('The Bible Multiversion', style: TextStyle(
fontSize: 20
),),
centerTitle: true,
),
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: ListView.separated(
shrinkWrap: true,
itemCount: booknames.length,
separatorBuilder: (BuildContext context, int index) =>
Divider(height: 1),
itemBuilder: (context, index) {
return Column(
children: [
GestureDetector(
onTap: () {
int increament = index 1;
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation1, animation2) =>
chapters(increament, booknames[index]),
transitionDuration: Duration(seconds: 0),
),
);
// Navigator.push(
// context,
// MaterialPageRoute(builder: (context) => chapters(increament)),
// );
},
child: ListTile(
leading: CircleAvatar(
radius: 20,
backgroundColor: Colors.primaries[Random().nextInt(
Colors.primaries.length)],
child: Text(
booknames[index].substring(0, 1), style: TextStyle(
fontSize: 17,
fontWeight: FontWeight.bold,
color: Colors.white
),),
),
title: Text(
booknames[index], style: TextStyle(
color: Colors.black,
fontSize: 20
),
),
),
),
],
);
},
),
),
],
),
);
}
//this voice listener method
void _listen() async {
if (!islistening) {
bool available = await speechToText.initialize(
onStatus: (val) => print('onStatus: $val'),
one rror: (val) => print('onError: $val'),
);
if (available) {
setState(() {
islistening=true;
});
speechToText.listen(
onResult: (result)=>setState(() {
//this text is not updating in dialog
text=result.recognizedWords;
//but this print method continues printing spkoen word in console
print('result.recognizedWords')
})
);
}
} else {
setState(() => islistening = false
);
speechToText.stop();
}
}
}
CodePudding user response:
I think this is a common problem, setState does not work for dialog, because Dialog is not the part of the tree.
this is showDialog()
's document:
/// This function takes a `builder` which typically builds a [Dialog] widget.
/// Content below the dialog is dimmed with a [ModalBarrier]. The widget
/// returned by the `builder` does not share a context with the location that
/// `showDialog` is originally called from. Use a [StatefulBuilder] or a
/// custom [StatefulWidget] if the dialog needs to update dynamically.
you can use StatefulBuilder, refer to How to refresh an AlertDialog in Flutter?