Hello friends i am working on speech recognition in flutter i made custom alert dialogue like native dialog when user click on button alert dialog appear and when user speak it show text on alert dialog my problem is that i want when user finishing his speech alert dialogue will automatically close please let me know how i can perform this task?
stt.SpeechToText speechToText = stt.SpeechToText();
bool islistening = false;
late String text = 'Example:Genesis chapter 1 verse 5';
bool complete=false;
final GlobalKey _dialogKey = GlobalKey();
ValueNotifier<bool> buttonClickedTimes =ValueNotifier(false);
_showDialog() async {
showDialog(
context:context,
barrierDismissible: true,
builder: (BuildContext context) {
return StatefulBuilder(
key: _dialogKey,
builder: (context, setState) {
return Container(
child: Dialog(
child: Padding(
padding: const EdgeInsets.all(8),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const AvatarGlow(
glowColor: Colors.blue,
endRadius: 80,
duration: Duration( milliseconds: 2500),
repeat: true,
showTwoGlows: true,
repeatPauseDuration: Duration( milliseconds: 150),
child: Material(
elevation: 5,
shape: CircleBorder(),
child: CircleAvatar(
backgroundColor: Colors.white,
child: Icon(Icons.mic, color: Colors.blue, size: 40,),
radius: 40,
),
),
),
Text(text),
const SizedBox(height: 10),
TextButton(
onPressed: () => Navigator.pop(context, false), // passing false
child: const Text('Cancel Voice'),
),
],
),
),
),
);
},
);
},
);
}
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey();
void _listen() async {
if (!islistening) {
bool available = await speechToText.initialize(
onStatus: (val) => print('onStatus: $val'),
onError: (val) => print('onError: $val'),
);
if (available) {
setState(() {
islistening = true;
});
speechToText.listen(
onResult: (result) =>
setState(() {
text = result.recognizedWords;
if (_dialogKey.currentState != null && _dialogKey.currentState!.mounted && speechToText.isListening) {
_dialogKey.currentState!.setState(() {
text =result.recognizedWords;
});}
else{
if(text.contains('Genesis')){
setState(() {
String bigSentence =text;
var voice= bigSentence.split(" ");
var bookname=voice[0];
var booknumber=1;
int chapternumber=int.parse(voice[2]);
int versenumber=int.parse(voice[4]);
if(_regExp.hasMatch(chapternumber.toString())&&_regExp.hasMatch(versenumber.toString())){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Allverse(bookname, booknumber,chapternumber, versenumber)),
);
}else{
Fluttertoast.showToast(
msg: "check chapter number or versenumber",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0
);
}
});
}
}
})
);
}
} else
{
setState(() => islistening = false);
speechToText.stop();
}
}
Related
hello guys!
i am using flutter story view package to implement story functionality in my app and i am using camera plugin to record video and upload, however the content type of the uploaded video is application/octet-stream when i receive it on my server and only when it is sent from ios. for android everything is fine and i get the content type as video/mp4.
can you guys please help me.
i have not done anything fancy i have just used the basic functionality of start recording and stop recording of the camra plugin.
// ignore_for_file: use_build_context_synchronously
List<CameraDescription>? cameras;
class CameraScreen extends StatefulWidget {
const CameraScreen({Key? key}) : super(key: key);
#override
State<CameraScreen> createState() => _CameraScreenState();
}
class _CameraScreenState extends State<CameraScreen> {
CameraController? _cameraController;
Future<void>? cameraValue;
bool flash = false;
bool iscamerafront = true;
static const _maxSeconds = 30;
ValueNotifier<bool> visible = ValueNotifier(false);
ValueNotifier<bool> isRecoring = ValueNotifier(false);
TimerProvider? _timerProvider;
#override
void initState() {
super.initState();
_timerProvider = Provider.of(context, listen: false);
_cameraController = CameraController(cameras![0], ResolutionPreset.veryHigh,
imageFormatGroup: ImageFormatGroup.bgra8888);
cameraValue = _cameraController?.initialize();
_cameraController?.prepareForVideoRecording();
lockCamera();
}
lockCamera() async {
await _cameraController!.lockCaptureOrientation();
}
#override
void dispose() {
super.dispose();
visible.dispose();
isRecoring.dispose();
_cameraController?.dispose();
}
#override
Widget build(BuildContext context) {
print("camera_screen");
final size = MediaQuery.of(context).size;
return Scaffold(
extendBodyBehindAppBar: true,
appBar: AppBar(
centerTitle: true,
title: ValueListenableBuilder<bool>(
valueListenable: visible,
builder: (context, value, child) {
return Visibility(
visible: value,
child: Container(
padding: const EdgeInsets.all(10),
width: 50,
height: 50,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.black.withOpacity(0.5)),
child: Center(
child: Consumer<TimerProvider>(
builder: (context, value, child) {
if (value.seconds == 0) {
if (_cameraController!.value.isRecordingVideo) {
stopRecording();
}
}
return Text(
value.seconds.toString(),
style: CustomStyles.fixAppBarTextStyle
.copyWith(color: Colors.white),
);
}),
),
));
}),
backgroundColor: Colors.transparent,
leadingWidth: 100,
leading: InkWell(
onTap: () {
Navigator.pop(context);
},
child: Center(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"Cancel",
style: CustomStyles.fixMediumBodyTextStyle
.copyWith(color: Colors.white),
),
)),
),
),
body: SafeArea(
top: false,
child: Stack(
children: [
FutureBuilder(
future: cameraValue,
builder: (context, snapshot) {
_cameraController?.lockCaptureOrientation();
if (snapshot.connectionState == ConnectionState.done) {
return Transform.scale(
scale: size.aspectRatio *
_cameraController!.value.aspectRatio <
1
? 1 /
(size.aspectRatio *
_cameraController!.value.aspectRatio)
: size.aspectRatio *
_cameraController!.value.aspectRatio,
child: Center(child: CameraPreview(_cameraController!)),
);
} else {
return const Center(
child: CircularProgressIndicator.adaptive(),
);
}
}),
Positioned(
bottom: 0.0,
child: Container(
padding: const EdgeInsets.only(top: 5, bottom: 5),
width: Dimensions.screenWidth,
child: Column(
children: [
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
padding: const EdgeInsets.all(4),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.black.withOpacity(0.5)),
child: Center(
child: IconButton(
icon: Icon(
flash ? Icons.flash_on : Icons.flash_off,
color: Colors.white,
size: 28,
),
onPressed: () {
setState(() {
flash = !flash;
});
flash
? _cameraController!
.setFlashMode(FlashMode.torch)
: _cameraController!
.setFlashMode(FlashMode.off);
}),
),
),
ValueListenableBuilder<bool>(
valueListenable: isRecoring,
builder: (context, value, child) {
return GestureDetector(
onLongPress: () {
startRecording();
},
onLongPressUp: () {
stopRecording();
},
onTap: () {
if (value == false) {
takePhoto(context);
}
},
child: value == true
? const CircleAvatar(
radius: 50,
backgroundColor: Colors.white30,
child: CircleAvatar(
radius: 35,
backgroundColor: Colors.red,
),
)
: const CircleAvatar(
radius: 35,
backgroundColor: Colors.white30,
child: CircleAvatar(
radius: 25,
backgroundColor: Colors.white,
),
));
}),
Container(
padding: const EdgeInsets.all(4),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.black.withOpacity(0.5)),
child: IconButton(
icon: const Icon(
Icons.flip_camera_ios,
color: Colors.white,
size: 28,
),
onPressed: () async {
setState(() {
iscamerafront = !iscamerafront;
});
int cameraPos = iscamerafront ? 0 : 1;
_cameraController = CameraController(
cameras![cameraPos], ResolutionPreset.high);
cameraValue = _cameraController?.initialize();
}),
),
],
),
addVerticalSpace(6),
const Text(
"Hold for Video, tap for photo",
style: TextStyle(
color: Colors.white,
),
textAlign: TextAlign.center,
),
addVerticalSpace(5),
],
),
),
),
],
),
),
);
}
void startRecording() async {
visible.value = true;
_timerProvider?.startCountDown(_maxSeconds);
isRecoring.value = true;
await _cameraController?.startVideoRecording();
}
void stopRecording() async {
XFile videopath = await _cameraController!.stopVideoRecording();
_timerProvider?.stopTimer();
isRecoring.value = false;
Navigator.push(
context,
MaterialPageRoute(
builder: (builder) => CameraResult(
image: File(videopath.path),
isImage: false,
))).then((value) {
visible.value = false;
});
}
void takePhoto(BuildContext context) async {
XFile file = await _cameraController!.takePicture();
SystemSound.play(SystemSoundType.click);
final img.Image? capturedImage =
img.decodeImage(await File(file.path).readAsBytes());
final img.Image orientedImage = img.flipHorizontal(capturedImage!);
File finalImage =
await File(file.path).writeAsBytes(img.encodeJpg(orientedImage));
Navigator.push(
context,
CupertinoPageRoute(
builder: (builder) => CameraResult(
image: finalImage,
isImage: true,
))).then((value) {
visible.value = false;
});
}
}
the upload function is as bellow
{File? shouts,
File? thumbnail,
int? duration,
bool? isImage,
required String userId,
required OnUploadProgressCallback onUploadProgress}) async {
assert(shouts != null);
try {
var url = Constants.POSTSHOUTURL;
final httpClient = FileService.getHttpClient();
final request = await httpClient.postUrl(Uri.parse(url));
int byteCount = 0;
var multipart;
if (isImage == false) {
multipart = await http.MultipartFile.fromPath(
'story-media', shouts!.path,
contentType: MediaType("video", "mp4"));
} else {
multipart = await http.MultipartFile.fromPath(
'story-media',
shouts!.path,
);
}
var multipart2 =
await http.MultipartFile.fromPath('thumbnail', thumbnail!.path);
var requestMultipart = http.MultipartRequest('POST', Uri.parse(url));
requestMultipart.fields["userid"] = userId.toString();
requestMultipart.fields["duration"] = duration.toString();
requestMultipart.headers['Content-type'] = 'multipart/form-data';
requestMultipart.files.add(multipart);
requestMultipart.files.add(multipart2);
var msStream = requestMultipart.finalize();
var totalByteLength = requestMultipart.contentLength;
request.contentLength = totalByteLength;
request.headers.add(HttpHeaders.authorizationHeader,
"Bearer ${Hive.box<UserData>(Constants.userDb).get(Hive.box<UserData>(Constants.userDb).keyAt(0))!.token}");
request.headers.set(HttpHeaders.contentTypeHeader,
requestMultipart.headers[HttpHeaders.contentTypeHeader]!);
Stream<List<int>> streamUpload = msStream.transform(
StreamTransformer.fromHandlers(
handleData: (data, sink) {
sink.add(data);
byteCount += data.length;
if (onUploadProgress != null) {
onUploadProgress(byteCount, totalByteLength);
// CALL STATUS CALLBACK;
}
},
handleError: (error, stack, sink) {
throw error;
},
handleDone: (sink) {
sink.close();
// UPLOAD DONE;
},
),
);
await request.addStream(streamUpload);
final httpResponse = await request.close();
var statusCode = httpResponse.statusCode;
if (statusCode ~/ 100 == 2) {
onUploadProgress(0, 0);
return await FileService.readResponseAsString(httpResponse);
}
return "";
} on SocketException {
throw FetchDataException("No internet to upload Shout!");
}
}```
i have used necessary info.plist setting also
I am trying to show an CircularProgressIndicator whenever user presses on register button, here is my code:
onPressed: () async{
if (_email.isNotEmpty && _password.isNotEmpty) {
startProgressIndicator();
FirebaseAuth mAuth = FirebaseAuth.instance;
UserCredential credential = await mAuth.createUserWithEmailAndPassword(email: _email, password: _password);
print(credential.user!.email);
//stopProgressIndicator();
} else {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(
"Please enter all information!",
style: TextStyle(
color: Colors.white,
fontSize: 15,
fontWeight: FontWeight.bold
),
),
backgroundColor: Colors.black,
elevation: 5,
duration: Duration(
seconds: 3
),
action: SnackBarAction(
label: "close",
onPressed: (){
ScaffoldMessenger.of(context).hideCurrentSnackBar();
},
),
));
}
startProgressIndicator():
CircularProgressIndicator startProgressIndicator() {
return CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.orange),
backgroundColor: Colors.black,
strokeWidth: 5,
);
}
stopProgressIndicator():
CircularProgressIndicator stopProgressIndicator() {
return CircularProgressIndicator(
value: 0,
);
}
The loading icon doesn't appear at all.
All colors are correct(i.e. background color and progress bar color are different)
What is the issue here?
EDIT: I added the following code but it still isn't working:
Column(
children: [
<Other widgets>
Visibility(
visible: _isProgressVisible,
child: CircularProgressIndicator(),
)
]
)
and I set _isProgressVisible to true and false:
if (_email.isNotEmpty && _password.isNotEmpty) {
setState(() {
_isProgressVisible = true;
});
FirebaseAuth mAuth = FirebaseAuth.instance;
UserCredential credential = await mAuth.createUserWithEmailAndPassword(email: _email, password: _password);
print(credential.user!.email);
setState(() {
_isProgressVisible = false;
});
}
You are not showing the returned widget anywhere, startProgressIndicator() returns the widget but you're just calling not rendering it,
Either use like this
showCupertinoDialog(
useRootNavigator: true,
barrierDismissible: false,
context: context,
builder: (context) {
return startProgressIndicator();
},
);
If you want to show that somewhere else you can do that like this
Container(
margin: const EdgeInsets.all(16),
child: Column(children: [
Visibility(
visible: showIndicator,
child: startProgressIndicator()),
const SizedBox(height: 10),
RaisedButton(
child: const Text('Here'),
onPressed: () => setState(() => showIndicator = !showIndicator),
)
]),
);
return startProgressIndicator();
That's just simple mistake
You have to return widget;
I have a page code written in an android studio. On this page, I display a list of objects, as well as a widget to search for these objects. When I clicked on the search widget, I had the following problem: "The following statement was thrown during layout:
RenderFlex is overcrowded 31 pixels below.
The corresponding widget that caused the errors was: "But then I found the answer to this question and added" SingleChildScrollView ".
But then I had this problem: "RenderFlex have non-zero flexibility, but the input height limits are unlimited." . And I can't solve it in any way. I will be grateful for your help. Here is my code:
import 'package:flutter/material.dart';
import 'package:flutter_app_seals/model/post/form_unseals.dart';
import 'package:flutter_app_seals/model/post/form_seals.dart';
import 'package:flutter_app_seals/model/setting/globalvar.dart' as global;
import 'dart:async';
import 'dart:io';
import 'dart:convert';
void main() => runApp(JsonParseObjectSts_UN());
class JsonParseObjectSts_UN extends StatefulWidget {
JsonParseObjectSts_UN() : super();
#override
_JsonParseObjectsState createState() => _JsonParseObjectsState();
}
class _JsonParseObjectsState extends State <StatefulWidget> {
List<UserDetails> _searchResult = [];
List<UserDetails> _userDetails = [];
TextEditingController controller = new TextEditingController();
final String url = global.urlVar ;
// Get json result and convert it to model. Then add
Future<Null> getUserDetails() async {
HttpClient client = new HttpClient();
client.badCertificateCallback = ((X509Certificate cert, String host, int port) => true);
final request = await client
.getUrl(Uri.parse(url))
.timeout(Duration(seconds: 5));
HttpClientResponse response = await request.close();
var responseBody = await response.transform(utf8.decoder).join();
final responseJson = json.decode(responseBody);
setState(() {
for (Map user in responseJson) {
_userDetails.add(UserDetails.fromJson(user));
}
});
}
#override
void initState() {
super.initState();
getUserDetails();
}
Widget _buildUsersList() {
return new ListView.builder(
itemCount: _userDetails.length,
itemBuilder: (context, index) {
return new Card(
color: (_userDetails[index].sealed == "Так") ? Colors.redAccent : Colors.greenAccent,
margin: EdgeInsets.symmetric(vertical: 7),
child: ListTile(
title: Text(
_userDetails[index].name,
style: TextStyle(fontSize: 25),
),
subtitle: Text("Запломбований:${_userDetails[index].sealed}"),
leading: Icon(
Icons.home_outlined,
size: 30,
color: Colors.black87,
),
onTap: () =>
{
if ('Так' == _userDetails[index].sealed) {
global.nameObj = _userDetails[index].name,
global.sealsNumb = _userDetails[index].seal_number,
global.typesOp = 'Так',
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Unseals()),
)
}
else{
{
global.nameObj = _userDetails[index].name,
global.typesOp = 'Ні',
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Form_seals()),
)
}
}
}
),
);
},
);
}
Widget _buildSearchResults() {
return new ListView.builder(
itemCount: _searchResult.length,
itemBuilder: (context, i) {
return new Card(
color: (_searchResult[i].sealed == "Так") ? Colors.redAccent : Colors.greenAccent,
margin: EdgeInsets.symmetric(vertical: 7),
child: ListTile(
title: Text(
_searchResult[i].name,
style: TextStyle(fontSize: 25),
),
subtitle: Text("Запломбований:${_searchResult[i].sealed}"),
leading: Icon(
Icons.home_outlined,
size: 30,
color: Colors.black87,
),
onTap: () =>
{
if ('Так' == _searchResult[i].sealed) {
global.nameObj = _searchResult[i].name,
global.sealsNumb = _searchResult[i].seal_number,
global.typesOp = 'Так',
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Unseals()),
)
}
else{
{
global.nameObj = _searchResult[i].name,
global.typesOp = 'Ні',
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Form_seals()),
)
}
}
}
),
);
},
);
}
Widget _buildSearchBox() {
return new Padding(
padding: const EdgeInsets.all(8.0),
child: new Card(
child: new ListTile(
leading: new Icon(Icons.search),
title: new TextField(
controller: controller,
decoration: new InputDecoration(
hintText: 'Пошук', border: InputBorder.none),
onChanged: onSearchTextChanged,
),
trailing: new IconButton(
icon: new Icon(Icons.cancel),
onPressed: () {
controller.clear();
onSearchTextChanged('');
},
),
),
),
);
}
Widget _buildBody() {
return new Scaffold(
body:Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.blue, Colors.white],
begin: Alignment.topCenter,
end: Alignment.bottomCenter),
),
child: SingleChildScrollView(
child:Column(
children: <Widget>[
new Container(
color: Theme.of(context).primaryColor, child: _buildSearchBox()),
new Expanded(
child: _searchResult.length != 0 || controller.text.isNotEmpty
? _buildSearchResults()
: _buildUsersList()),
],
),
),
),
);
}
#override
Widget build(BuildContext context) {
return new Scaffold(
body: _buildBody()
);
}
onSearchTextChanged(String text) async {
_searchResult.clear();
if (text.isEmpty) {
setState(() {});
return;
}
_userDetails.forEach((userDetail) {
if (userDetail.name.contains(text) ) _searchResult.add(userDetail);
});
setState(() {});
}
}
class UserDetails {
final String name, seal_number,sealed;
UserDetails({this.name, this.sealed, this.seal_number});
factory UserDetails.fromJson(Map<String, dynamic> json) {
return new UserDetails(
sealed: json['sealed'],
name: json['name'],
seal_number: json['seal_number'],
);
}
}
My scrin:
My scrin when I want to use search:
I have a page code written in an android studio. On this page, I display a list of objects, as well as a widget to search for these objects. When I clicked on the search widget,my list of objects is shrinking, and it is almost invisible (it is at the top). Can this be fixed somehow so that it can be seen on the whole page ??
import 'package:flutter/material.dart';
import 'package:flutter_app_seals/model/post/form_unseals.dart';
import 'package:flutter_app_seals/model/post/form_seals.dart';
import 'package:flutter_app_seals/model/setting/globalvar.dart' as global;
import 'dart:async';
import 'dart:io';
import 'dart:convert';
void main() => runApp(JsonParseObjectSts_UN());
class JsonParseObjectSts_UN extends StatefulWidget {
JsonParseObjectSts_UN() : super();
#override
_JsonParseObjectsState createState() => _JsonParseObjectsState();
}
class _JsonParseObjectsState extends State <StatefulWidget> {
List<UserDetails> _searchResult = [];
List<UserDetails> _userDetails = [];
TextEditingController controller = new TextEditingController();
final String url = global.urlVar ;
// Get json result and convert it to model. Then add
Future<Null> getUserDetails() async {
HttpClient client = new HttpClient();
client.badCertificateCallback = ((X509Certificate cert, String host, int port) => true);
final request = await client
.getUrl(Uri.parse(url))
.timeout(Duration(seconds: 5));
HttpClientResponse response = await request.close();
var responseBody = await response.transform(utf8.decoder).join();
final responseJson = json.decode(responseBody);
setState(() {
for (Map user in responseJson) {
_userDetails.add(UserDetails.fromJson(user));
}
});
}
#override
void initState() {
super.initState();
getUserDetails();
}
Widget _buildUsersList() {
return new ListView.builder(
itemCount: _userDetails.length,
itemBuilder: (context, index) {
return new Card(
color: (_userDetails[index].sealed == "Так") ? Colors.redAccent : Colors.greenAccent,
margin: EdgeInsets.symmetric(vertical: 7),
child: ListTile(
title: Text(
_userDetails[index].name,
style: TextStyle(fontSize: 25),
),
subtitle: Text("Запломбований:${_userDetails[index].sealed}"),
leading: Icon(
Icons.home_outlined,
size: 30,
color: Colors.black87,
),
onTap: () =>
{
if ('Так' == _userDetails[index].sealed) {
global.nameObj = _userDetails[index].name,
global.sealsNumb = _userDetails[index].seal_number,
global.typesOp = 'Так',
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Unseals()),
)
}
else{
{
global.nameObj = _userDetails[index].name,
global.typesOp = 'Ні',
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Form_seals()),
)
}
}
}
),
);
},
);
}
Widget _buildSearchResults() {
return new ListView.builder(
itemCount: _searchResult.length,
itemBuilder: (context, i) {
return new Card(
color: (_searchResult[i].sealed == "Так") ? Colors.redAccent : Colors.greenAccent,
margin: EdgeInsets.symmetric(vertical: 7),
child: ListTile(
title: Text(
_searchResult[i].name,
style: TextStyle(fontSize: 25),
),
subtitle: Text("Запломбований:${_searchResult[i].sealed}"),
leading: Icon(
Icons.home_outlined,
size: 30,
color: Colors.black87,
),
onTap: () =>
{
if ('Так' == _searchResult[i].sealed) {
global.nameObj = _searchResult[i].name,
global.sealsNumb = _searchResult[i].seal_number,
global.typesOp = 'Так',
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Unseals()),
)
}
else{
{
global.nameObj = _searchResult[i].name,
global.typesOp = 'Ні',
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Form_seals()),
)
}
}
}
),
);
},
);
}
Widget _buildSearchBox() {
return new Padding(
padding: EdgeInsets.all(7.0),
child: new Card(
child: new ListTile(
leading: new Icon(Icons.search),
title: new TextField(
controller: controller,
decoration: new InputDecoration(
hintText: 'Пошук', border: InputBorder.none),
onChanged: onSearchTextChanged,
),
trailing: new IconButton(
icon: new Icon(Icons.cancel),
onPressed: () {
controller.clear();
onSearchTextChanged('');
},
),
),
),
);
}
Widget _buildBody() {
return new Scaffold(
body:Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.blue, Colors.white],
begin: Alignment.topCenter,
end: Alignment.bottomCenter),
),
child:Column(
children: <Widget>[
new Expanded( flex: 1, child: _buildSearchBox()),
new Expanded(flex:8,
child: _searchResult.length != 0 || controller.text.isNotEmpty
? _buildSearchResults()
: _buildUsersList()),
],
),
),
);
}
#override
Widget build(BuildContext context) {
return new Scaffold(
body: _buildBody()
);
}
onSearchTextChanged(String text) async {
_searchResult.clear();
if (text.isEmpty) {
setState(() {});
return;
}
_userDetails.forEach((userDetail) {
if (userDetail.name.contains(text) ) _searchResult.add(userDetail);
});
setState(() {});
}
}
class UserDetails {
final String name, seal_number,sealed;
UserDetails({this.name, this.sealed, this.seal_number});
factory UserDetails.fromJson(Map<String, dynamic> json) {
return new UserDetails(
sealed: json['sealed'],
name: json['name'],
seal_number: json['seal_number'],
);
}
}
My page:
My page with search:
I have looked at your code several times, I just noticed a small error.
For the results of your searches, you try to display the "List" of searches in a ListView.builder, which is in a column in the parent container does not have a defined height.
Solution: Set a height for the main container and the problem will be solved
I want to get an integer value in Future function which must be compared in a if condition when i'm pressing my fab button but instead of getting the number of documents in the collection it's giving in the log console 'Instance of Future' but I need my method to return a number.
this is my code:
class MembresPage extends StatefulWidget {
#override
_MembresPageState createState() => _MembresPageState();
}
class _MembresPageState extends State<MembresPage> {
Map<String, String> sublingData = {};
String nomComplet;
String adresse;
String ldNais;
QuerySnapshot subling;
CrudMethods crudObj = new CrudMethods();
Future<bool> addDialog(BuildContext context) async{
return showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context){
return AlertDialog(
title: Text('Ajouter Membre', style: TextStyle(fontSize: 15.0)),
content: Column(
children: <Widget>[
TextField(
decoration: InputDecoration(hintText: 'Nom Complet'),
onChanged: (value){
this.nomComplet =value;
},
),
SizedBox(height: 8.0),
TextField(
decoration: InputDecoration(hintText: 'Ex: Kinshasa, le 21/12/1960'),
onChanged: (value){
this.ldNais = value;
},
),
SizedBox(height: 8.0),
TextField(
decoration: InputDecoration(hintText: 'Adresse'),
onChanged: (value){
this.adresse = value;
},
),
],
),
actions: <Widget>[
FlatButton(
child: Text('Ajouter'),
textColor: Colors.deepOrangeAccent[400],
onPressed: () async {
Navigator.of(context).pop();
sublingData = {
'nomComplet':this.nomComplet,
'ldNais': this.ldNais,
'adresse':this.adresse
};
PaiementStripe().addMembers(sublingData).then((result){
dialogTrigger(context);
}).catchError((e){
print(e);
});
},
)
],
);
});
}
Future<bool> updateDialog(BuildContext context, selectedDoc) async{
return showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context){
return AlertDialog(
title: Text('Modifier Membre', style: TextStyle(fontSize: 15.0)),
content: Column(
children: <Widget>[
TextField(
decoration: InputDecoration(hintText: 'Nom Complet'),
onChanged: (value){
this.nomComplet =value;
},
),
SizedBox(height: 8.0),
TextField(
decoration: InputDecoration(hintText: 'Ex: Kinshasa, le 21/12/1960'),
onChanged: (value){
this.ldNais = value;
},
),
SizedBox(height: 8.0),
TextField(
decoration: InputDecoration(hintText: 'Adresse'),
onChanged: (value){
this.adresse = value;
},
),
],
),
actions: <Widget>[
FlatButton(
child: Text('Modifier'),
textColor: Colors.deepOrangeAccent[400],
onPressed: (){
Navigator.of(context).pop();
/*sublingData = {
'nomComplet':this.nomSubling,
'lieuNais': this.lieuNais,
'dateNais':this.dateNais
};*/
PaiementStripe().updateMembers(selectedDoc,{
'nomComplet':this.nomComplet,
'ldNais': this.ldNais,
'adresse':this.adresse
}).then((result){
//dialogTrigger(context);
}).catchError((e){
print(e);
});
PaiementStripe().getMembers().then((result){
setState(() {
subling = result;
});
});
},
)
],
);
});
}
Future<bool> dialogTrigger(BuildContext context) async{
return showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context){
return AlertDialog(
title: Text('Info', style: TextStyle(fontSize: 15.0)),
content: Text('Membre ajouté'),
actions: <Widget>[
FlatButton(
child: Text('OK'),
textColor: Colors.deepOrangeAccent[400],
onPressed: (){
PaiementStripe().getMembers().then((result){
setState(() {
subling = result;
});
});
Navigator.of(context, rootNavigator: true).pop();
},
)
],
);
});
}
void showSnackBar(BuildContext context, docID){
var snackBar = SnackBar(
content: Text("Voulez vous Supprimer le membre?"),
action: SnackBarAction(
label: "OUI",
onPressed: (){
PaiementStripe().deleteMembers(docID);
PaiementStripe().getMembers().then((result){
setState(() {
subling = result;
});
});
}
),
);
Scaffold.of(context).showSnackBar(snackBar);
}
void seeSnackBar(BuildContext context){
var snackBar = SnackBar(
content: Text("Vous avez le maximum de membres"),
);
Scaffold.of(context).showSnackBar(snackBar);
}
#override
void initState(){
PaiementStripe().getMembers().then((result){
setState(() {
subling = result;
});
});
super.initState();
}
// the method that I need to return an Integer value
Future<int> countDocuments() async {
FirebaseUser user = await FirebaseAuth.instance.currentUser();
QuerySnapshot _myDoc = await Firestore.instance.collection('users').document(user.uid).collection('sublings').getDocuments();
List<DocumentSnapshot> _myDocCount = _myDoc.documents;
return _myDocCount.length;
//Count of Documents in Collection
}
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton:Column(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
FloatingActionButton(
heroTag: 'fab1',
onPressed: (){
//the test comparison
if (countDocuments() < 5){
addDialog(context);
print(countDocuments());
}
else{
seeSnackBar(context);
}
},
child: Icon(
Icons.add,
color: Colors.white,
),
backgroundColor: Colors.deepOrangeAccent,
),
]
),
body:_sublingList(),
);
}
Widget _sublingList(){
if(subling!=null){
return ListView.separated(
itemCount: subling.documents.length,
padding: EdgeInsets.all(5.0),
itemBuilder: (context, i){
return ListTile(
leading: Icon(Icons.account_circle,
size: 60.0,),
title: Text(subling.documents[i].data['nomComplet'],
style: TextStyle(
fontWeight: FontWeight.bold,
fontFamily: 'OpenSans'
),),
subtitle: Text(subling.documents[i].data['ldNais'] +'\n'+subling.documents[i].data['adresse']),
onTap: (){
updateDialog(context, subling.documents[i].documentID);
PaiementStripe().getMembers().then((result){
setState(() {
subling = result;
});
});
},
onLongPress: (){
showSnackBar(context,subling.documents[i].documentID);
},
);
},
separatorBuilder: (context, i){
return Divider();
},
);
}
else{
return Center(
child: CircularProgressIndicator(),
);
}
}
}
when I am pressing the fab button, I am getting this message:
Instance of Future'dynamic'
5 //which is the number of documents
that's why it's not possible to compare it
you need to await the Future function to finish
onPressed: () async {
//the test comparison
int count = await countDocuments();
if (count < 5){
addDialog(context);
print(countDocuments());
}
else{
seeSnackBar(context);
}
},
you can do that
void getCount(){
countDocuments().then((count ) {
// print(result);
if (count < 5){
addDialog(context);
print(countDocuments());
}
else{
seeSnackBar(context);
}
});
}