I was designing an audio player, the slider isn't working and the audio keeps on playing even when I press pause. I have attached the code and log.
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:geolocator/geolocator.dart';
import 'package:image_picker/image_picker.dart';
import 'package:intl/intl.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/services.dart';
import 'package:video_player/video_player.dart';
import 'package:audioplayers/audioplayers.dart';
import '../login.dart';
import 'package:flutter/services.dart';
class bestPractises extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _bestPractises();
}
}
class _bestPractises extends State<bestPractises> {
VideoPlayerController _controller;
Future<void> _initializeVideoPlayerFuture;
AudioPlayer audioPlayer= new AudioPlayer();
Duration duration = new Duration();
Duration position = new Duration();
bool playing = false;
String Lat = "",
Lng = "";
List<DropdownMenuItem> primtopicsitems = [];
String slctprimtopics = "",slcttopics="";
List<ImageProductSaleModel> imageList = new List();
List<UImodel> bpListUIModel = new List();
List<UImodel> topicListUIModel = new List();
List<DropdownMenuItem> bestpractitems = [],topicitems=[];
File farmerImageFile;
String AudioBase64 = "";
String audioPath = "";
bool isRecord = false;
TextEditingController remarksController = new TextEditingController();
TextEditingController txtmesgController = new TextEditingController();
TextEditingController precadvicController = new TextEditingController();
File fileMedia;
MediaSource source;
String vedio64 = "";
void initState() {
super.initState();
print("inistate");
initvalues();
getLocation();
// _controller = VideoPlayerController.asset(dataSource);
//_initializeVideoPlayerFuture = _controller.initialize();
//_controller.setLooping(true);
// getClientData();
}
void dispose() {
//_controller.dispose();
super.dispose();
}
Future<void> initvalues() async {
List bpList = await db.RawQuery('select * from animalCatalog where catalog_code=\'140\'');
print('bpList ' + bpList.toString());
bpListUIModel = new List();
bestpractitems.clear();
for (int i = 0; i < bpList.length; i++) {
String ptName = bpList[i]["property_value"].toString();
String ptCode = bpList[i]["DISP_SEQ"].toString();
var uimodel = new UImodel(ptName, ptCode);
bpListUIModel.add(uimodel);
setState(() {
bestpractitems.add(DropdownMenuItem(
child: Text(ptName),
value: ptCode,
));
});
}
List topicList = await db.RawQuery('select * from animalCatalog where catalog_code=\'140\'');
print('topicList ' + topicList.toString());
topicListUIModel = new List();
topicitems.clear();
for (int i = 0; i < topicList.length; i++) {
String topicName = topicList[i]["property_value"].toString();
String topicCode = topicList[i]["DISP_SEQ"].toString();
var uimodel = new UImodel(topicName, topicCode);
topicListUIModel.add(uimodel);
setState(() {
topicitems.add(DropdownMenuItem(
child: Text(topicName),
value: topicCode,
));
});
}
}
Future<bool> _onBackPressed() {
return Alert(
context: context,
type: AlertType.warning,
title: "Cancel",
desc: "Are you sure want to cancel?",
buttons: [
DialogButton(
child: Text(
"Yes",
style: TextStyle(color: Colors.white, fontSize: 20),
),
onPressed: () {
Navigator.pop(context);
Navigator.pop(context);
},
width: 120,
),
DialogButton(
child: Text(
"No",
style: TextStyle(color: Colors.white, fontSize: 20),
),
onPressed: () {
Navigator.pop(context);
},
width: 120,
)
],
).show() ??
false;
}
void getLocation() async {
bool isLocationEnabled = await Geolocator.isLocationServiceEnabled();
if (isLocationEnabled) {
Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high);
print("latitude :" +
position.latitude.toString() +
" longitude: " +
position.longitude.toString());
setState(() {
Lat = position.latitude.toString();
Lng = position.longitude.toString();
});
} else {
Alert(
context: context,
title: "Information",
desc: "GPS Location not enabled",
buttons: [
DialogButton(
child: Text(
"OK",
style: TextStyle(color: Colors.white, fontSize: 18),
),
onPressed: () {
Navigator.pop(context);
Navigator.pop(context);
},
color: Colors.green,
)
]).show();
}
}
Widget build(BuildContext context) {
return SafeArea(
child: WillPopScope(
onWillPop: _onBackPressed,
child: Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
centerTitle: true,
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () {
_onBackPressed();
}),
title: Text(
'Best Practices',
style: new TextStyle(
color: Colors.white,
fontSize: 18.0,
fontWeight: FontWeight.w700),
),
iconTheme: IconThemeData(color: Colors.white),
backgroundColor: Colors.green,
brightness: Brightness.light,
),
body: Container(
child: Column(children: <Widget>[
Expanded(
child: ListView(
padding: EdgeInsets.all(10.0),
children: _getbpListings(
context), // <<<<< Note this change for the return type
),
flex: 8,
),
])),
),
),
);
}
List<Widget> _getbpListings(BuildContext context) {
List listings = List<Widget>();
listings.add(txt_label(
"Primary Topic", Colors.black, 16.0, false));
listings.add(singlesearchDropdown(
itemlist: bestpractitems,
selecteditem: slctprimtopics,
hint: "Select the Primary Topic",
onChanged: (value) {
setState(() {
slctprimtopics = value;
});
}));
listings.add(txt_label(
"Topic", Colors.black, 16.0, false));
listings.add(singlesearchDropdown(
itemlist: topicitems,
selecteditem: slcttopics,
hint: "Select the Topic",
onChanged: (value) {
setState(() {
slcttopics = value;
});
}));
// listings.add(txt_label(
// "\nText Messages ", Colors.black, 16.0, false));
listings.add(Row(
children: <Widget>[
Expanded(
child: Row(
children: <Widget>[
Expanded(
flex: 3,
child: txt_label(
"\nText Messages ", Colors.black, 16.0, false)
//),
),
Expanded(
flex: 4,
child: txt_label(
"\nBuyer 1 ", Colors.black, 16.0, false)
),
],
),
),
],
),
);
// listings
// .add(txtfield_dynamic("", txtmesgController, true));
listings.add(Row(
children: <Widget>[
Expanded(
child: Row(
children: <Widget>[
Expanded(
flex: 3,
child: txt_label(
"\nPrecautionary \n Advices ", Colors.black, 16.0, false)
//),
),
Expanded(
flex: 4,
child: txt_label(
"\n This is the Advisory Message ", Colors.black, 16.0, false)
),
],
),
),
],
),
);
// listings.add(txt_label(
// "Precautionary Advices", Colors.black, 16.0, false));
//
// listings
// .add(txtfield_dynamic("", precadvicController, true));
listings.add(Row(
children: <Widget>[
Expanded(
child: Row(
children: <Widget>[
Expanded(
flex: 3,
child: txt_label(
"\nManuals ", Colors.black, 16.0, false)
//),
),
Expanded(
flex: 4,
child: txt_label(
"\n This is the Advisory Message ", Colors.black, 16.0, false)
),
],
),
),
],
),
);
// listings.add(txt_label(
// "Manuals ", Colors.black, 16.0, false));
//
// listings
// .add(txtfield_dynamic("", precadvicController, true));
listings.add(txt_label("\nPhotos of the Advices", Colors.black, 16.0, false));
listings.add( Row(
children: [
Image(
image: AssetImage('images/1.jpg'),
height: 375,
width: 375,
),
const SizedBox(height: 24),
],
),
);
/* listings.add( Row(
FutureBuilder (
future: _initializeVideoPlayerFuture,
builder: (context,snapshot)
{
if(snapshot.connectionState == ConnectionState.done)
{
return AspectRatio(aspectRatio: _controller.value.aspectRatio,
child: VideoPlayer(_controller),
);
}else {
return Center(
child : CircularProgressIndicator(),
);
}
},
),
floatingActionButton: FloatingActionButton(
onpressed : (){
setState(() {
if(_controller.value.isPlaying) {
_controller.pause();
} else {
_controller.play();
}
});
}
child:
Icon(_controller.value.isPlaying ? Icons.pause : Icons.play_arrow),
),
),
); */
// listings.add(img_picker(
// label: "Photos of the Advices \*",
// onPressed: () {
// getImage();
// },
// filename: farmerImageFile,
// ondelete: () {
// ondelete();
// }));
listings.add(txt_label("Video", Colors.black, 16.0, false));
listings.add( Row(
children: [
RaisedButton(
child: Text('\Video'),
onPressed: () => capture(MediaSource.video),
color: Colors.green,
textColor: Colors.white,
),
const SizedBox(height: 24),
Expanded(
child: fileMedia == null
? Container()
: (source == MediaSource.video
? Column(
children: [
VideoWidget(fileMedia),
],
)
: Container()),
),
],
),
);
listings.add(txt_label("\nAudio", Colors.black, 16.0, false));
listings.add(Container(
color: Colors.white,
child: Column(
children: <Widget> [
//Image(image: AssetImage(''),),
slider(),
InkWell(
onTap: () {
getAudio();
},
child:Icon(
playing == false
? Icons.play_circle_outline
: Icons.pause_circle_outline,
size: 50,
color: Colors.blue,
),
)
],
),
),
);
listings.add(btn_dynamic(
label: "Audio",
bgcolor: Colors.green,
txtcolor: Colors.white,
fontsize: 18.0,
centerRight: Alignment.centerLeft,
margin: 10.0,
btnSubmit: () async {
audioPath = await Navigator.push(context,
MaterialPageRoute(builder: (context) => AudioRecorder()));
File audioFile = new File(audioPath);
List<int> fileBytes = await audioFile.readAsBytes();
AudioBase64 = base64Encode(fileBytes);
setState(() {
isRecord = true;
});
}));
if (isRecord) {
listings.add(Container(
color: Colors.blueGrey,
height: 40,
child: Center(
child: Row(
children: [
Expanded(
child: Center(
child: txt_label(
audioPath.split('/').last, Colors.white, 14.0, false)),
flex: 3,
),
Expanded(
child: InkWell(
onTap: () {
setState(() {
isRecord = false;
});
},
child: Icon(Icons.delete, color: Colors.red)),
flex: 1,
)
],
),
),
));
}
listings.add(txt_label("\nRemarks", Colors.black, 14.0, false));
listings.add(txtfield_dynamic("Remarks", remarksController, true));
/* listings.add(Container(
child: Row(
children: [
Expanded(
flex: 1,
child: Container(
padding: EdgeInsets.all(3),
child: RaisedButton(
child: Text(
'Cancel',
style: new TextStyle(color: Colors.white, fontSize: 18),
),
onPressed: () {
_onBackPressed();
},
color: Colors.red,
),
),
),
Expanded(
flex: 1,
child: Container(
padding: EdgeInsets.all(3),
child: RaisedButton(
child: Text(
'Submit',
style: new TextStyle(color: Colors.white, fontSize: 18),
),
onPressed: () {
_bestpractisessubmit();
},
color: Colors.green,
),
),
),
//
],
),
)); */
return listings;
}
Widget slider() {
return Slider.adaptive(
min: 0.0,
value: position.inSeconds.toDouble(),
max: duration.inSeconds.toDouble(),
onChanged : (double value) {
setState(() {
audioPlayer.seek(new Duration(seconds: value.toInt()));
});
}
);
}
void getAudio() async {
var url = "https://www.learningcontainer.com/wp-content/uploads/2020/02/Kalimba.mp3";
if (playing) {
var res = await audioPlayer.pause();
if(res == 1) {
setState(() {
playing = false;
});
}
} else {
var res = await audioPlayer.play(url,isLocal: true);
if(res == 1) {
setState(() {
playing = true;
});
}
}
audioPlayer.onDurationChanged.listen((Duration dd) {
setState(() {
duration = dd;
});
});
audioPlayer.onAudioPositionChanged.listen((Duration dd) {
setState(() {
position = dd;
});
});
}
void _bestpractisessubmit() async{
if (slctprimtopics == "") {
errordialog(context, "Information",
"Primary Topic should not be empty");
}else if (slcttopics == ''){
errordialog(context, "Information",
"Topic should not be empty");
}else{
Alert(
context: context,
type: AlertType.info,
title: "Information",
desc: "Are you sure want to proceed?",
buttons: [
DialogButton(
child: Text(
"Yes",
style: TextStyle(color: Colors.white, fontSize: 20),
),
onPressed: () {
Navigator.pop(context);
Navigator.pop(context);
Navigator.pop(context);
},
width: 120,
),
DialogButton(
child: Text(
"No",
style: TextStyle(color: Colors.white, fontSize: 20),
),
onPressed: () {
Navigator.pop(context);
},
width: 120,
)
],
).show() ??
false;
}
}
Future getImage() async {
var image = await ImagePicker.platform
.pickImage(source: ImageSource.camera, imageQuality: 30);
setState(() {
farmerImageFile = new File(image.path);
});
}
void ondelete() {
setState(() {
if (farmerImageFile != null) {
setState(() {
farmerImageFile = null;
});
}
});
}
Future capture(MediaSource source) async {
setState(() {
this.source = source;
this.fileMedia = null;
});
final result = await Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => SourcePage(),
settings: RouteSettings(
arguments: source,
),
),
);
if (result == null) {
return;
} else {
setState(() {
fileMedia = result;
});
}
}
}
log:
[ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception:
setState() called after dispose(): _bestPractises#e42c5(lifecycle
state: defunct, not mounted)
This error happens if you call setState() on a State object for a widget that no longer appears in the widget tree (e.g., whose parent
widget no longer includes the widget in its build). This error can
occur when code calls setState() from a timer or an animation
callback.
The preferred solution is to cancel the timer or stop listening to the animation in the dispose() callback. Another solution is to check
the "mounted" property of this object before calling setState() to
ensure the object is still in the tree.
This error might indicate a memory leak if setState() is being called because another object is retaining a reference to this State
object after it has been removed from the tree. To avoid memory leaks,
consider breaking the reference to this object during dispose().
#0 State.setState. (package:flutter/src/widgets/framework.dart:1052:9)
#1 State.setState (package:flutter/src/widgets/framework.dart:1087:6)
#2 _bestPractises.getAudio. (package:aftab/Screens/bestPractisesscreen.dart:611:7)
#3 _rootRunUnary (dart:async/zone.dart:1362:47)
#4 _CustomZone.runUnary (dart:async/zone.dart:1265:19)
#5 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1170:7)
#6 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
#7 _DelayedData.perform (dart:async/stream_impl.dart:591:14)
#8 _StreamImplEvents.handleNext (dart:async/stream_impl.dart:706:11)
#9 _PendingEvents.schedule. (dart:async/stream_impl.dart:663:7)
#10 _rootRun (dart:async/zone.dart:1346:47)
#11 _CustomZone.run (dart:async/zone.dart:1258:19)
#12 _CustomZone.runGuarded (dart:async/zone.dart:1162:7)
#13 _CustomZone.bindCallbackGuarded. (dart:async/zone.dart:1202:23)
#14 _rootRun (dart:async/zone.dart:1354:13)
#15 _CustomZone.run (dart:async/zone.dart:1258:19)
#16 _CustomZone.runGuarded (dart:async/zone.dart:1162:7)
#17 _CustomZone.bindCallbackGuarded. (dart:async/zone.dart:1202:23)
#18 _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
#19 _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)
Related
this is my code
import 'package:flutter/src/widgets/container.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:intl/intl.dart';
import 'package:flutter/material.dart';
class NewTransaction extends StatefulWidget {
final Function addTx;
NewTransaction(this.addTx);
#override
State<NewTransaction> createState() => _NewTransactionState();
}
class _NewTransactionState extends State<NewTransaction> {
final _titleController = TextEditingController();
final _amountController = TextEditingController();
DateTime _selectedDate;
void _submitData() {
final enteredTitle = _titleController.text;
final enteredAmount = double.parse(_amountController.text);
if (enteredTitle.isEmpty || enteredAmount <= 0) {
return;
}
widget.addTx(
enteredTitle,
enteredAmount,
);
Navigator.of(context).pop();
}
void _presentDatePicker() {
showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime(2019),
lastDate: DateTime.now(),
).then((pickedDate) {
if (pickedDate == null) {
return;
}
setState(() {
_selectedDate = pickedDate;
});
});
print('...');
}
#override
Widget build(BuildContext context) {
return Card(
elevation: 5,
child: Container(
padding: EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
TextField(
decoration: InputDecoration(labelText: 'Title'),
controller: _titleController,
onSubmitted: (_) => _submitData(),
// onChanged: (val) {
// titleInput = val;
// },
),
TextField(
decoration: InputDecoration(labelText: 'Amount'),
keyboardType: TextInputType.number,
onSubmitted: (_) => _submitData(),
controller: _amountController,
// onChanged: (val) => amountInput = val,
),
Container(
height: 70,
child: Row(
children: <Widget>[
Expanded(
child: Text(
_selectedDate == null
? 'No Date Chosen!'
: 'Picked Date: ${DateFormat.yMd().format(_selectedDate)}',
),
),
TextButton(
child: Text(
'Choose Date',
style: TextStyle(
color: Theme.of(context).primaryColor,
fontWeight: FontWeight.bold,
),
),
onPressed: _presentDatePicker,
)
],
),
),
ElevatedButton(
child: Text(
'Add Transaction',
style: TextStyle(
color: Colors.white,
),
),
onPressed: _submitData,
style: ButtonStyle(
backgroundColor: MaterialStateProperty.resolveWith(
(states) {
return Colors.purple;
},
),
),
),
],
),
),
);
}
}
there's a redline on DateTime _selectedDate;
what should I do?
You're trying to make it null in the code so that you check over it with e _selectedDate == null.
well, you can tell Dart that it can be null from its declaration with a ?:
DateTime? _selectedDate; // add ?
I am getting the following error when trying to upload a photo to firebase in Uint8list format
The following _CastError was thrown building AddPostScreen(dirty, dependencies:
[_LocalizationsScope-[GlobalKey#e5b12], _InheritedProviderScope<UserProvider?>], state:
_AddPostScreenState#61568):
Null check operator used on a null value
The relevant error-causing widget was:
AddPostScreen
AddPostScreen:file:///C:/Users/rehan/Desktop/clone/lib/responsive/mobile_screen_layout.dart:53:11
When the exception was thrown, this was the stack:
#0 UserProvider.getUser (package:clone/providers/user_provider.dart:9:28)
#1 _AddPostScreenState.build (package:clone/screens/add_post_screen.dart:160:38)
#2 StatefulElement.build (package:flutter/src/widgets/framework.dart:4870:27)
#3 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4754:15)
#4 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4928:11)
#5 Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5)
#6 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2659:19)
#7 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:882:21)
#8 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:363:5)
#9 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1144:15)
#10 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1081:9)
#11 SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:995:5)
#15 _invoke (dart:ui/hooks.dart:151:10)
#16 PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:308:5)
#17 _drawFrame (dart:ui/hooks.dart:115:31)
(elided 3 frames from dart:async)
Here is the mobileScreen Code
import 'package:clone/utility/colors.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../screens/add_post_screen.dart';
import '../screens/feed_screen.dart';
class Mobile extends StatefulWidget {
const Mobile({Key? key}) : super(key: key);
#override
State<Mobile> createState() => _MobileState();
}
class _MobileState extends State<Mobile> {
int _page = 0;
late PageController _pageController;
#override
void initState() {
super.initState();
_pageController = PageController();
}
#override
void dispose() {
super.dispose();
_pageController.dispose();
}
void navigationTapped(int page) {
_pageController.jumpToPage(page);
}
void onPageChanged(int page) {
setState(() {
_page = page;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: PageView(
children: [
FeedScreen(),
const Text('search'),
AddPostScreen(),
const Text('notifications'),
const Text('profile'),
],
physics: const NeverScrollableScrollPhysics(),
controller: _pageController,
onPageChanged: onPageChanged,
),
bottomNavigationBar: CupertinoTabBar(
items: [
BottomNavigationBarItem(
icon: Icon(
Icons.home,
color: _page == 0 ? primaryColor : secondaryColor,
),
label: '',
backgroundColor: primaryColor),
BottomNavigationBarItem(
icon: Icon(
Icons.search,
color: _page == 1 ? primaryColor : secondaryColor,
),
label: '',
backgroundColor: primaryColor),
BottomNavigationBarItem(
icon: Icon(
Icons.add_circle,
color: _page == 2 ? primaryColor : secondaryColor,
),
label: '',
backgroundColor: primaryColor),
BottomNavigationBarItem(
icon: Icon(
Icons.favorite,
color: _page == 3 ? primaryColor : secondaryColor,
),
label: '',
backgroundColor: primaryColor),
BottomNavigationBarItem(
icon: Icon(
Icons.person,
color: _page == 4 ? primaryColor : secondaryColor,
),
label: '',
backgroundColor: primaryColor),
],
onTap: navigationTapped,
),
);
}
}
Here is the AddPost Code
import 'dart:typed_data';
import 'package:clone/providers/user_provider.dart';
import 'package:clone/utility/colors.dart';
import 'package:flutter/material.dart';
import 'package:clone/utility/utils.dart';
import 'package:image_picker/image_picker.dart';
import 'package:provider/provider.dart';
import '../resources/firestore_methods.dart';
class AddPostScreen extends StatefulWidget {
const AddPostScreen({Key? key}) : super(key: key);
#override
_AddPostScreenState createState() => _AddPostScreenState();
}
class _AddPostScreenState extends State<AddPostScreen> {
Uint8List? _file;
bool isLoading = false;
final TextEditingController _descriptionController = TextEditingController();
_selectImage(BuildContext parentContext) async {
return showDialog(
context: parentContext,
builder: (BuildContext context) {
return SimpleDialog(
title: const Text('Create a Post'),
children: <Widget>[
SimpleDialogOption(
padding: const EdgeInsets.all(20),
child: const Text('Take a photo'),
onPressed: () async {
Navigator.pop(context);
Uint8List file = await pickIamge(ImageSource.camera);
setState(() {
_file = file;
});
}),
SimpleDialogOption(
padding: const EdgeInsets.all(20),
child: const Text('Choose from Gallery'),
onPressed: () async {
Navigator.of(context).pop();
Uint8List file = await pickIamge(ImageSource.gallery);
setState(() {
_file = file;
});
}),
SimpleDialogOption(
padding: const EdgeInsets.all(20),
child: const Text("Cancel"),
onPressed: () {
Navigator.pop(context);
},
)
],
);
},
);
}
void clearImage() {
setState(() {
_file = null;
});
}
void postImage(String uid, String username, String profImage) async {
setState(() {
isLoading = true;
});
// start the loading
try {
// upload to storage and db
String res = await FireStoreMethods().uploadPost(
_descriptionController.text,
_file!,
uid,
username,
profImage,
);
if (res == "success") {
setState(() {
isLoading = false;
});
showSnackBar('Posted', context);
clearImage();
} else {
showSnackBar(res, context);
}
} catch (e) {
setState(() {
isLoading = false;
});
showSnackBar(e.toString(), context);
}
}
#override
void dispose() {
super.dispose();
_descriptionController.dispose();
}
#override
Widget build(BuildContext context) {
final UserProvider userProvider = Provider.of<UserProvider>(context);
return _file == null
? Center(
child: IconButton(
icon: const Icon(
Icons.upload,
),
onPressed: () => _selectImage(context),
),
)
: Scaffold(
appBar: AppBar(
backgroundColor: mobileBackgroundColor,
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: clearImage,
),
title: const Text(
'Post to',
),
centerTitle: false,
actions: <Widget>[
TextButton(
onPressed: () => postImage(
userProvider.getUser.uid,
userProvider.getUser.username,
userProvider.getUser.photoUrl,
),
child: const Text(
"Post",
style: TextStyle(
color: Colors.blueAccent,
fontWeight: FontWeight.bold,
fontSize: 16.0),
),
)
],
),
// POST FORM
body: Column(
children: <Widget>[
isLoading
? const LinearProgressIndicator()
: const Padding(padding: EdgeInsets.only(top: 0.0)),
const Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
CircleAvatar(
backgroundImage: NetworkImage(
userProvider.getUser.photoUrl,
),
),
SizedBox(
width: MediaQuery.of(context).size.width * 0.3,
child: TextField(
controller: _descriptionController,
decoration: const InputDecoration(
hintText: "Write a caption...",
border: InputBorder.none),
maxLines: 8,
),
),
SizedBox(
height: 45.0,
width: 45.0,
child: AspectRatio(
aspectRatio: 487 / 451,
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.fill,
alignment: FractionalOffset.topCenter,
image: MemoryImage(_file!),
)),
),
),
),
],
),
const Divider(),
],
),
);
}
}
Initially I the screen is fine, but when I try to upload a photo either from the gallery or from the camera the error comes Null check operator used on a null value, even though I am setting the value of _file when trying to upload the photo.
I need to detect when my phoneCall variable changes state this to detect when the call ended and show a modal to the user so he can rate the call. This is the widget code.
import 'dart:convert';
import 'package:avanx/flutter/loading_view.dart';
import 'package:avanx/globals.dart';
import 'package:avanx/models/group.dart';
import 'package:avanx/models/prospect.dart';
import 'package:cool_alert/cool_alert.dart';
import 'package:flutter_phone_state/flutter_phone_state.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:url_launcher/url_launcher.dart';
import '../flutter/theme.dart';
import 'package:avanx/flutter/input_widget.dart';
import '../flutter/widgets.dart';
import 'package:flutter/material.dart';
import 'package:avanx/flutter/drawer_widget.dart';
import 'package:loading_animations/loading_animations.dart';
import 'package:http/http.dart' as http;
class LeadsHomeWidget extends StatefulWidget {
LeadsHomeWidget({Key key}) : super(key: key);
#override
_LeadsHomeWidgetState createState() => _LeadsHomeWidgetState();
}
class _LeadsHomeWidgetState extends State<LeadsHomeWidget> {
List<dynamic> _leads = [];
List<dynamic> _groups;
var phoneCall;
TextEditingController textController;
final scaffoldKey = GlobalKey<ScaffoldState>();
GlobalKey<FormState> _formKey = GlobalKey();
String _search = '';
_initCall(_number) async {
setState(() {
phoneCall = FlutterPhoneState.startPhoneCall(_number);
});
}
showCallInfo() {
print(phoneCall
.status); // ringing, dialing, cancelled, error, connecting, connected, timedOut, disconnected
print(phoneCall.isComplete); // Whether the call is complete
print(phoneCall
.events); // A list of call events related to this specific call
}
// Metodo para la obtención de los grupos existentes.
getGroups() async {
print("hello");
final response = await http.get(Uri.parse(Globals.avanx + '/groups'),
headers: {"Accept": "application/json"});
if (response.statusCode == 200) {
var groupsList = json.decode(response.body)['groups'];
List<dynamic> groups =
groupsList.map((element) => new Group.fromJson(element)).toList();
setState(() {
_groups = groups;
});
} else {
throw Exception('Failed to load groups');
}
}
getLeads(name) async {
if (name != '') {
String auth = Globals.authUser.user.id.toString();
final response = await http.post(
Uri.parse(Globals.avanx + '/prospects/search/$auth'),
body: {'name': name},
headers: {"Accept": "application/json"});
if (response.statusCode == 200) {
var leadsList = json.decode(response.body)['leads'];
List<dynamic> leads =
leadsList.map((element) => new Prospect.fromJson(element)).toList();
setState(() {
_leads = leads;
});
} else {
throw Exception('Failed to load leads');
}
} else {
setState(() {
_leads = [];
});
}
}
deleteModal(id) {
CoolAlert.show(
context: context,
animType: null,
type: CoolAlertType.warning,
title: '¿Estas Seguro?',
text: "Esta acción no se puede reversar.",
backgroundColor: Color(0xBF35126A),
confirmBtnText: 'Confirmar',
confirmBtnColor: Color(0xBF35126A),
showCancelBtn: true,
cancelBtnText: 'Cancelar',
onConfirmBtnTap: () {
deleteLead(id);
Navigator.pop(context);
});
}
deleteLead(id) async {
final response = await http.delete(
Uri.parse(Globals.avanx + '/prospects/$id'),
headers: {"Accept": "application/json"});
if (response.statusCode == 200) {
_search = '';
this.getLeads(_search);
} else {
throw Exception('Failed to load leads');
}
}
#override
void initState() {
textController = TextEditingController();
this.getGroups();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: scaffoldKey,
backgroundColor: FlutterTheme.tertiaryColor,
appBar: AppBar(
backgroundColor: FlutterTheme.primaryColor,
title: Text(
'Prospectos',
style: TextStyle(fontFamily: 'Montserrat'),
),
centerTitle: true,
),
drawer: DrawerWidget(),
body: _groups == null
? LoadingWidget()
: Align(
alignment: Alignment(0, 0),
child: Padding(
padding: EdgeInsets.fromLTRB(30, 10, 30, 0),
child: ListView(
padding: EdgeInsets.zero,
scrollDirection: Axis.vertical,
children: _groups == null
? []
: [
Form(
key: _formKey,
child: Row(
children: [
Expanded(
flex: 2,
child: Container(
padding:
EdgeInsets.symmetric(horizontal: 15),
child: InputWidget(
label: 'Buscar prospecto?',
keyBoardType: TextInputType.text,
onChanged: (text) {
_search = text;
},
validator: (text) {
if (text.trim().length == 0) {
return "input data";
}
return null;
},
),
),
),
Expanded(
child: ElevatedButton(
child: Text(
'Buscar',
style: TextStyle(
color: FlutterTheme.primaryColor),
),
onPressed: () {
getLeads(_search);
},
style: ElevatedButton.styleFrom(
side: BorderSide(
width: 1.5,
color: FlutterTheme.primaryColor,
),
primary: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
),
),
),
],
),
),
phoneCall.isComplete
? Container(
child: Text('The call is end!!'),
)
: Container(),
for (var lead in _leads ?? [])
Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Slidable(
actionPane: SlidableDrawerActionPane(),
actionExtentRatio: 0.25,
child: Container(
color: Colors.white,
child: ListTile(
leading: CircleAvatar(
backgroundImage: NetworkImage(
'https://ui-avatars.com/api/?name=' +
lead.name +
'&background=35126A&color=fff&size=128'),
),
title: Text(lead.name),
subtitle: Text(
'Grupo: ' + lead.group.name,
style: TextStyle(fontSize: 11),
),
trailing: Container(
width: 100,
child: Row(
children: [
IconButton(
onPressed: () {
_initCall(lead.phone);
},
icon: Icon(
Icons.phone,
size: 35,
color: Color(0xFF35126A),
)),
IconButton(
onPressed: () {
showCallInfo();
},
icon: Icon(
Icons.mail_outline,
size: 35,
color: Color(0xFF35126A),
)),
],
),
),
),
),
secondaryActions: <Widget>[
IconSlideAction(
onTap: () {
Navigator.pushNamed(context, 'leads_edit',
arguments: lead);
},
caption: 'Edit',
color: Color(0xFF35126A),
icon: Icons.edit,
),
IconSlideAction(
onTap: () {
deleteModal(lead.id);
},
caption: 'Delete',
color: Colors.red,
icon: Icons.delete,
),
],
),
),
Padding(
padding: EdgeInsets.fromLTRB(0, 40, 0, 0),
child: ButtonWidget(
onPressed: () {
Navigator.pushNamed(context, 'leads_add_new');
},
text: 'Agregar Nuevo',
options: ButtonOptions(
width: 130,
height: 40,
color: FlutterTheme.tertiaryColor,
textStyle: FlutterTheme.subtitle2.override(
fontFamily: 'Montserrat',
color: FlutterTheme.primaryColor,
),
borderSide: BorderSide(
color: FlutterTheme.primaryColor,
width: 2,
),
borderRadius: 30,
),
),
),
Padding(
padding: EdgeInsets.fromLTRB(0, 40, 0, 0),
child: Text(
'Grupos',
textAlign: TextAlign.center,
style: FlutterTheme.bodyText1.override(
fontFamily: 'Montserrat',
color: Color(0xBF35126A),
fontSize: 20,
),
),
),
for (var group in _groups)
Padding(
padding: EdgeInsets.fromLTRB(0, 20, 0, 0),
child: ButtonWidget(
onPressed: () {
Navigator.pushNamed(context, 'leads_list',
arguments: group);
},
text: group.name,
options: ButtonOptions(
width: 130,
height: 40,
color: FlutterTheme.primaryColor,
textStyle: FlutterTheme.subtitle2.override(
fontFamily: 'Montserrat',
color: Colors.white,
),
borderSide: BorderSide(
color: Colors.transparent,
width: 1,
),
borderRadius: 30,
),
),
),
],
),
),
),
);
}
}
The function _initCall is the one in charge of initializing the call, so the variable phoneCall will have the information of the state of the call, I want to launch a modal when the call finishes.
hello I am working on a app that lets users upload audio from their devices to a account profile. here is the code I have for the profile page:
import 'dart:io';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:mix/model/MessageData.dart';
import 'package:mix/model/User.dart';
import 'package:mix/services/FirebaseHelper.dart';
import 'package:mix/services/helper.dart';
import 'package:mix/ui/accountDetails/AccountDetailsScreen.dart';
import 'package:mix/ui/auth/AuthScreen.dart';
import 'package:mix/ui/contactUs/ContactUsScreen.dart';
import 'package:mix/ui/fullScreenImageViewer/FullScreenImageViewer.dart';
import 'package:mix/ui/settings/SettingsScreen.dart';
import 'package:mix/ui/upgradeAccount/UpgradeAccount.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:image_picker/image_picker.dart';
import 'package:page_view_indicators/circle_page_indicator.dart';
import '../../constants.dart';
import '../../main.dart';
class ProfileScreen extends StatefulWidget {
final User user;
ProfileScreen({Key key, #required this.user}) : super(key: key);
#override
_ProfileScreenState createState() => _ProfileScreenState(user);
}
class _ProfileScreenState extends State<ProfileScreen> {
final ImagePicker _imagePicker = ImagePicker();
User user;
FireStoreUtils _fireStoreUtils = FireStoreUtils();
final _currentPageNotifier = ValueNotifier<int>(0);
_ProfileScreenState(this.user);
List images = List();
List _pages = [];
List<Widget> _gridPages = [];
#override
void initState() {
images.clear();
images.addAll(user.photos);
if (images.isNotEmpty) {
if (images[images.length - 1] != null) {
images.add(null);
}
} else {
images.add(null);
}
super.initState();
}
#override
Widget build(BuildContext context) {
_gridPages = _buildGridView();
return Scaffold(
body: SingleChildScrollView(
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: <
Widget>[
Padding(
padding: const EdgeInsets.only(top: 16.0, left: 32, right: 32),
child: Stack(
alignment: Alignment.bottomCenter,
children: <Widget>[
Center(
child:
displayCircleImage(user.profilePictureURL, 130, false)),
Positioned(
left: 80,
right: 0,
child: FloatingActionButton(
backgroundColor: Color(COLOR_ACCENT),
child: Icon(
Icons.camera_alt,
color:
isDarkMode(context) ? Colors.black : Colors.white,
),
mini: true,
onPressed: _onCameraClick),
)
],
),
),
Padding(
padding: const EdgeInsets.only(top: 16.0, right: 32, left: 32),
child: SizedBox(
width: double.infinity,
child: Text(
user.fullName(),
style: TextStyle(
color: isDarkMode(context) ? Colors.white : Colors.black,
fontSize: 20),
textAlign: TextAlign.center,
),
),
),
Padding(
padding: const EdgeInsets.only(top: 16.0, left: 16, right: 16),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: skipNulls([
Text(
'My Music',
textAlign: TextAlign.start,
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
_pages.length >= 2
? CirclePageIndicator(
selectedDotColor: Color(COLOR_ACCENT),
dotColor: Colors.grey,
itemCount: _pages.length,
currentPageNotifier: _currentPageNotifier,
)
: null
]),
),
),
Padding(
padding: EdgeInsets.only(top: 16, bottom: 8),
child: SizedBox(
height: user.photos.length > 3 ? 260 : 130,
width: double.infinity,
child: PageView(
children: _gridPages,
onPageChanged: (int index) {
_currentPageNotifier.value = index;
},
)),
),
Column(
children: <Widget>[
ListTile(
dense: true,
onTap: () {
push(context, new AccountDetailsScreen(user: user));
},
title: Text(
'Account Details',
style: TextStyle(fontSize: 16),
),
leading: Icon(
Icons.person,
color: Colors.blue,
),
),
ListTile(
dense: true,
onTap: () {
showModalBottomSheet(
isScrollControlled: true,
context: context,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(20),
),
),
builder: (context) {
return UpgradeAccount();
},
);
},
title: Text(
user.isVip != null && user.isVip
? 'Cancel subscription'
: 'Upgrade Account',
style: TextStyle(fontSize: 16),
),
leading: Image.asset(
'assets/images/vip.png',
height: 24,
width: 24,
),
),
ListTile(
dense: true,
onTap: () {
push(context, new SettingsScreen(user: user));
},
title: Text(
'Settings',
style: TextStyle(fontSize: 16),
),
leading: Icon(
Icons.settings,
color: isDarkMode(context) ? Colors.white70 : Colors.black45,
),
),
ListTile(
dense: true,
onTap: () {
push(context, new ContactUsScreen());
},
title: Text(
'Contact Us',
style: TextStyle(fontSize: 16),
),
leading: Icon(
Icons.call,
color: Colors.green,
),
),
],
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 24),
child: ConstrainedBox(
constraints: const BoxConstraints(minWidth: double.infinity),
child: FlatButton(
color: Colors.transparent,
child: Text(
'Logout',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: isDarkMode(context) ? Colors.white : Colors.black,
),
),
splashColor: isDarkMode(context)
? Colors.grey[700]
: Colors.grey.shade200,
onPressed: () async {
user.active = false;
user.lastOnlineTimestamp = Timestamp.now();
await FireStoreUtils.updateCurrentUser(user);
await FirebaseAuth.instance.signOut();
MyAppState.currentUser = null;
pushAndRemoveUntil(context, AuthScreen(), false);
},
padding: EdgeInsets.only(top: 12, bottom: 12),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
side: BorderSide(color: Colors.grey.shade200)),
),
),
),
]),
),
);
}
_onCameraClick() {
final action = CupertinoActionSheet(
message: Text(
"Add profile picture",
style: TextStyle(fontSize: 15.0),
),
actions: <Widget>[
CupertinoActionSheetAction(
child: Text("Remove Picture"),
isDestructiveAction: true,
onPressed: () async {
Navigator.pop(context);
showProgress(context, 'Removing picture...', false);
if (user.profilePictureURL.isNotEmpty)
await _fireStoreUtils.deleteImage(user.profilePictureURL);
user.profilePictureURL = '';
await FireStoreUtils.updateCurrentUser(user);
MyAppState.currentUser = user;
hideProgress();
setState(() {});
},
),
CupertinoActionSheetAction(
child: Text("Choose from gallery"),
onPressed: () async {
Navigator.pop(context);
PickedFile image =
await _imagePicker.getImage(source: ImageSource.gallery);
if (image != null) {
await _imagePicked(File(image.path));
}
setState(() {});
},
),
CupertinoActionSheetAction(
child: Text("Take a picture"),
onPressed: () async {
Navigator.pop(context);
PickedFile image =
await _imagePicker.getImage(source: ImageSource.camera);
if (image != null) {
await _imagePicked(File(image.path));
}
setState(() {});
},
),
],
cancelButton: CupertinoActionSheetAction(
child: Text("Cancel"),
onPressed: () {
Navigator.pop(context);
},
),
);
showCupertinoModalPopup(context: context, builder: (context) => action);
}
Future<void> _imagePicked(File image) async {
showProgress(context, 'Uploading image...', false);
user.profilePictureURL =
await _fireStoreUtils.uploadUserImageToFireStorage(image, user.userID);
await FireStoreUtils.updateCurrentUser(user);
MyAppState.currentUser = user;
hideProgress();
}
Widget _imageBuilder(String url) {
bool isLastItem = url == null;
return GestureDetector(
onTap: () {
isLastItem ? _pickImage() : _viewOrDeleteImage(url);
},
child: Card(
shape: RoundedRectangleBorder(
side: BorderSide.none,
borderRadius: BorderRadius.circular(12),
),
color: Color(COLOR_PRIMARY),
child: isLastItem
? Icon(
Icons.music_note,
size: 50,
color: isDarkMode(context) ? Colors.black : Colors.white,
)
: ClipRRect(
borderRadius: BorderRadius.circular(12),
child: CachedNetworkImage(
fit: BoxFit.cover,
imageUrl:
user.profilePictureURL == DEFAULT_AVATAR_URL ? '' : url,
placeholder: (context, imageUrl) {
return Icon(
Icons.hourglass_empty,
size: 75,
color: isDarkMode(context) ? Colors.black : Colors.white,
);
},
errorWidget: (context, imageUrl, error) {
return Icon(
Icons.error_outline,
size: 75,
color: isDarkMode(context) ? Colors.black : Colors.white,
);
},
),
),
),
);
}
List<Widget> _buildGridView() {
_pages.clear();
List<Widget> gridViewPages = [];
var len = images.length;
var size = 6;
for (var i = 0; i < len; i += size) {
var end = (i + size < len) ? i + size : len;
_pages.add(images.sublist(i, end));
}
_pages.forEach((elements) {
gridViewPages.add(GridView.builder(
padding: EdgeInsets.only(right: 16, left: 16),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
childAspectRatio: 1,
crossAxisSpacing: 10,
mainAxisSpacing: 10),
itemBuilder: (context, index) => _imageBuilder(elements[index]),
itemCount: elements.length,
physics: BouncingScrollPhysics()));
});
return gridViewPages;
}
_viewOrDeleteImage(String url) {
final action = CupertinoActionSheet(
actions: <Widget>[
CupertinoActionSheetAction(
onPressed: () async {
Navigator.pop(context);
images.removeLast();
images.remove(url);
await _fireStoreUtils.deleteImage(url);
user.photos = images;
User newUser =
await FireStoreUtils.updateCurrentUser(user);
MyAppState.currentUser = newUser;
user = newUser;
images.add(null);
setState(() {});
},
child: Text("Remove Picture"),
isDestructiveAction: true,
),
CupertinoActionSheetAction(
onPressed: () {
Navigator.pop(context);
push(context, FullScreenImageViewer(imageUrl: url));
},
isDefaultAction: true,
child: Text("View Picture"),
),
CupertinoActionSheetAction(
onPressed: () async {
Navigator.pop(context);
user.profilePictureURL = url;
user = await FireStoreUtils.updateCurrentUser(user);
setState(() {});
},
isDefaultAction: true,
child: Text("Make Profile Picture"),
)
],
cancelButton: CupertinoActionSheetAction(
child: Text("Cancel"),
onPressed: () {
Navigator.pop(context);
},
),
);
showCupertinoModalPopup(context: context, builder: (context) => action);
}
_pickImage() {
final action = CupertinoActionSheet(
message: Text(
"Add picture",
style: TextStyle(fontSize: 15.0),
),
actions: <Widget>[
CupertinoActionSheetAction(
child: Text("Choose from Files"),
isDefaultAction: false,
onPressed: () async {
Navigator.pop(context);
PickedFile image =
await _imagePicker.getImage(source: ImageSource.gallery);
if (image != null) {
Url imageUrl = await _fireStoreUtils.uploadChatImageToFireStorage(
File(image.path), context);
images.removeLast();
images.add(imageUrl.url);
user.photos = images;
User newUser =
await FireStoreUtils.updateCurrentUser(user);
MyAppState.currentUser = newUser;
user = newUser;
images.add(null);
setState(() {});
}
},
),
CupertinoActionSheetAction(
child: Text("Take a picture"),
isDestructiveAction: false,
onPressed: () async {
Navigator.pop(context);
PickedFile image =
await _imagePicker.getImage(source: ImageSource.camera);
if (image != null) {
Url imageUrl = await _fireStoreUtils.uploadChatImageToFireStorage(
File(image.path), context);
images.removeLast();
images.add(imageUrl.url);
user.photos = images;
User newUser =
await FireStoreUtils.updateCurrentUser(user);
MyAppState.currentUser = newUser;
user = newUser;
images.add(null);
setState(() {});
}
},
)
],
cancelButton: CupertinoActionSheetAction(
child: Text("Cancel"),
onPressed: () {
Navigator.pop(context);
},
),
);
showCupertinoModalPopup(context: context, builder: (context) => action);
}
#override
void dispose() {
_currentPageNotifier.dispose();
super.dispose();
}
}
any ideas on how to add a upload audio function to the my music section of the code?
any help is greatly appreciated. I'm still fairly new to flutter so please go easy on me :)
Thanks in advance!
first add the following packages:
firebase_storage:
gx_file_picker:
File file;//declare this
//on file choose button call this
try {
f = await FilePicker.getFile(
type: FileType.audio,
);
setState(() {
});
}catch(e){
//handle exception
}}
on your button on pressed event
onPressed:(){
upload(file);
}
upload(File fil)async{
String fileName = fil.path
.split('/')
.last;
StorageReference firebaseStorageRef =
FirebaseStorage.instance.ref().child('uploads/$fileName');
StorageUploadTask uploadTask = firebaseStorageRef.putFile(fil);
StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;
taskSnapshot.ref.getDownloadURL().then(
(value) {
});
}
hello I am working on a app that lets users upload audio from their devices to a account profile. I am getting a error when trying to create the upload audio action card.
here is the error I'm getting:
Positional arguments must occur before named arguments. Try moving
all of the positional arguments before the named arguments. Too many
positional arguments: 0 expected, but 2 found. Try removing the extra
positional arguments, or specifying the name for named arguments. Open
documentation
the error is on this line of code:
File file;
here is the code I have for the profile page:
import 'dart:io';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:gx_file_picker/gx_file_picker.dart';
import 'package:mix/model/MessageData.dart';
import 'package:mix/model/User.dart';
import 'package:mix/services/FirebaseHelper.dart';
import 'package:mix/services/helper.dart';
import 'package:mix/ui/accountDetails/AccountDetailsScreen.dart';
import 'package:mix/ui/auth/AuthScreen.dart';
import 'package:mix/ui/contactUs/ContactUsScreen.dart';
import 'package:mix/ui/fullScreenImageViewer/FullScreenImageViewer.dart';
import 'package:mix/ui/settings/SettingsScreen.dart';
import 'package:mix/ui/upgradeAccount/UpgradeAccount.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:image_picker/image_picker.dart';
import 'package:page_view_indicators/circle_page_indicator.dart';
import '../../constants.dart';
import '../../main.dart';
class ProfileScreen extends StatefulWidget {
final User user;
ProfileScreen({Key key, #required this.user}) : super(key: key);
#override
_ProfileScreenState createState() => _ProfileScreenState(user);
}
class _ProfileScreenState extends State<ProfileScreen> {
final ImagePicker _imagePicker = ImagePicker();
User user;
FireStoreUtils _fireStoreUtils = FireStoreUtils();
final _currentPageNotifier = ValueNotifier<int>(0);
_ProfileScreenState(this.user);
List images = List();
List _pages = [];
List<Widget> _gridPages = [];
#override
void initState() {
images.clear();
images.addAll(user.photos);
if (images.isNotEmpty) {
if (images[images.length - 1] != null) {
images.add(null);
}
} else {
images.add(null);
}
super.initState();
}
#override
Widget build(BuildContext context) {
_gridPages = _buildGridView();
return Scaffold(
body: SingleChildScrollView(
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: <
Widget>[
Padding(
padding: const EdgeInsets.only(top: 16.0, left: 32, right: 32),
child: Stack(
alignment: Alignment.bottomCenter,
children: <Widget>[
Center(
child:
displayCircleImage(user.profilePictureURL, 130, false)),
Positioned(
left: 80,
right: 0,
child: FloatingActionButton(
backgroundColor: Color(COLOR_ACCENT),
child: Icon(
Icons.camera_alt,
color:
isDarkMode(context) ? Colors.black : Colors.white,
),
mini: true,
onPressed: _onCameraClick),
)
],
),
),
Padding(
padding: const EdgeInsets.only(top: 16.0, right: 32, left: 32),
child: SizedBox(
width: double.infinity,
child: Text(
user.fullName(),
style: TextStyle(
color: isDarkMode(context) ? Colors.white : Colors.black,
fontSize: 20),
textAlign: TextAlign.center,
),
),
),
Padding(
padding: const EdgeInsets.only(top: 16.0, left: 16, right: 16),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: skipNulls([
Text(
'My Music',
textAlign: TextAlign.start,
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
_pages.length >= 2
? CirclePageIndicator(
selectedDotColor: Color(COLOR_ACCENT),
dotColor: Colors.grey,
itemCount: _pages.length,
currentPageNotifier: _currentPageNotifier,
)
: null
]),
),
),
Padding(
padding: EdgeInsets.only(top: 16, bottom: 8),
child: SizedBox(
height: user.photos.length > 3 ? 260 : 130,
width: double.infinity,
child: PageView(
children: _gridPages,
onPageChanged: (int index) {
_currentPageNotifier.value = index;
},
)),
),
Column(
children: <Widget>[
ListTile(
dense: true,
onTap: () {
push(context, new AccountDetailsScreen(user: user));
},
title: Text(
'Account Details',
style: TextStyle(fontSize: 16),
),
leading: Icon(
Icons.person,
color: Colors.blue,
),
),
ListTile(
dense: true,
onTap: () {
showModalBottomSheet(
isScrollControlled: true,
context: context,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(20),
),
),
builder: (context) {
return UpgradeAccount();
},
);
},
title: Text(
user.isVip != null && user.isVip
? 'Cancel subscription'
: 'Upgrade Account',
style: TextStyle(fontSize: 16),
),
leading: Image.asset(
'assets/images/vip.png',
height: 24,
width: 24,
),
),
ListTile(
dense: true,
onTap: () {
push(context, new SettingsScreen(user: user));
},
title: Text(
'Settings',
style: TextStyle(fontSize: 16),
),
leading: Icon(
Icons.settings,
color: isDarkMode(context) ? Colors.white70 : Colors.black45,
),
),
ListTile(
dense: true,
onTap: () {
push(context, new ContactUsScreen());
},
title: Text(
'Contact Us',
style: TextStyle(fontSize: 16),
),
leading: Icon(
Icons.call,
color: Colors.green,
),
),
],
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 24),
child: ConstrainedBox(
constraints: const BoxConstraints(minWidth: double.infinity),
child: FlatButton(
color: Colors.transparent,
child: Text(
'Logout',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: isDarkMode(context) ? Colors.white : Colors.black,
),
),
splashColor: isDarkMode(context)
? Colors.grey[700]
: Colors.grey.shade200,
onPressed: () async {
user.active = false;
user.lastOnlineTimestamp = Timestamp.now();
await FireStoreUtils.updateCurrentUser(user);
await FirebaseAuth.instance.signOut();
MyAppState.currentUser = null;
pushAndRemoveUntil(context, AuthScreen(), false);
},
padding: EdgeInsets.only(top: 12, bottom: 12),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
side: BorderSide(color: Colors.grey.shade200)),
),
),
),
]),
),
);
}
_onCameraClick() {
final action = CupertinoActionSheet(
message: Text(
"Add profile picture",
style: TextStyle(fontSize: 15.0),
),
actions: <Widget>[
CupertinoActionSheetAction(
child: Text("Remove Picture"),
isDestructiveAction: true,
onPressed: () async {
Navigator.pop(context);
showProgress(context, 'Removing picture...', false);
if (user.profilePictureURL.isNotEmpty)
await _fireStoreUtils.deleteImage(user.profilePictureURL);
user.profilePictureURL = '';
await FireStoreUtils.updateCurrentUser(user);
MyAppState.currentUser = user;
hideProgress();
setState(() {});
},
),
CupertinoActionSheetAction(
child: Text("Choose from gallery"),
onPressed: () async {
Navigator.pop(context);
PickedFile image =
await _imagePicker.getImage(source: ImageSource.gallery);
if (image != null) {
await _imagePicked(File(image.path));
}
setState(() {});
},
),
CupertinoActionSheetAction(
child: Text("Take a picture"),
onPressed: () async {
Navigator.pop(context);
PickedFile image =
await _imagePicker.getImage(source: ImageSource.camera);
if (image != null) {
await _imagePicked(File(image.path));
}
setState(() {});
},
),
],
cancelButton: CupertinoActionSheetAction(
child: Text("Cancel"),
onPressed: () {
Navigator.pop(context);
},
),
);
showCupertinoModalPopup(context: context, builder: (context) => action);
}
Future<void> _imagePicked(File image) async {
showProgress(context, 'Uploading image...', false);
user.profilePictureURL =
await _fireStoreUtils.uploadUserImageToFireStorage(image, user.userID);
await FireStoreUtils.updateCurrentUser(user);
MyAppState.currentUser = user;
hideProgress();
}
Widget _imageBuilder(String url) {
bool isLastItem = url == null;
return GestureDetector(
onTap: () {
isLastItem ? _pickAudio() : _viewOrDeleteImage(url);
},
child: Card(
shape: RoundedRectangleBorder(
side: BorderSide.none,
borderRadius: BorderRadius.circular(12),
),
color: Color(COLOR_PRIMARY),
child: isLastItem
? Icon(
Icons.music_note,
size: 50,
color: isDarkMode(context) ? Colors.black : Colors.white,
)
: ClipRRect(
borderRadius: BorderRadius.circular(12),
child: CachedNetworkImage(
fit: BoxFit.cover,
imageUrl:
user.profilePictureURL == DEFAULT_AVATAR_URL ? '' : url,
placeholder: (context, imageUrl) {
return Icon(
Icons.hourglass_empty,
size: 75,
color: isDarkMode(context) ? Colors.black : Colors.white,
);
},
errorWidget: (context, imageUrl, error) {
return Icon(
Icons.error_outline,
size: 75,
color: isDarkMode(context) ? Colors.black : Colors.white,
);
},
),
),
),
);
}
List<Widget> _buildGridView() {
_pages.clear();
List<Widget> gridViewPages = [];
var len = images.length;
var size = 6;
for (var i = 0; i < len; i += size) {
var end = (i + size < len) ? i + size : len;
_pages.add(images.sublist(i, end));
}
_pages.forEach((elements) {
gridViewPages.add(GridView.builder(
padding: EdgeInsets.only(right: 16, left: 16),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
childAspectRatio: 1,
crossAxisSpacing: 10,
mainAxisSpacing: 10),
itemBuilder: (context, index) => _imageBuilder(elements[index]),
itemCount: elements.length,
physics: BouncingScrollPhysics()));
});
return gridViewPages;
}
_viewOrDeleteImage(String url) {
final action = CupertinoActionSheet(
actions: <Widget>[
CupertinoActionSheetAction(
onPressed: () async {
Navigator.pop(context);
images.removeLast();
images.remove(url);
await _fireStoreUtils.deleteImage(url);
user.photos = images;
User newUser =
await FireStoreUtils.updateCurrentUser(user);
MyAppState.currentUser = newUser;
user = newUser;
images.add(null);
setState(() {});
},
child: Text("Remove Picture"),
isDestructiveAction: true,
),
CupertinoActionSheetAction(
onPressed: () {
Navigator.pop(context);
push(context, FullScreenImageViewer(imageUrl: url));
},
isDefaultAction: true,
child: Text("View Picture"),
),
CupertinoActionSheetAction(
onPressed: () async {
Navigator.pop(context);
user.profilePictureURL = url;
user = await FireStoreUtils.updateCurrentUser(user);
setState(() {});
},
isDefaultAction: true,
child: Text("Make Profile Picture"),
)
],
cancelButton: CupertinoActionSheetAction(
child: Text("Cancel"),
onPressed: () {
Navigator.pop(context);
},
),
);
showCupertinoModalPopup(context: context, builder: (context) => action);
}
_pickImage() {
final action = CupertinoActionSheet(
message: Text(
"Add picture",
style: TextStyle(fontSize: 15.0),
),
actions: <Widget>[
CupertinoActionSheetAction(
child: Text("Choose from Files"),
isDefaultAction: false,
onPressed: () async {
Navigator.pop(context);
PickedFile image =
await _imagePicker.getImage(source: ImageSource.gallery);
if (image != null) {
Url imageUrl = await _fireStoreUtils.uploadChatImageToFireStorage(
File(image.path), context);
images.removeLast();
images.add(imageUrl.url);
user.photos = images;
User newUser =
await FireStoreUtils.updateCurrentUser(user);
MyAppState.currentUser = newUser;
user = newUser;
images.add(null);
setState(() {});
}
},
),
CupertinoActionSheetAction(
child: Text("Take a picture"),
isDestructiveAction: false,
onPressed: () async {
Navigator.pop(context);
PickedFile image =
await _imagePicker.getImage(source: ImageSource.camera);
if (image != null) {
Url imageUrl = await _fireStoreUtils.uploadChatImageToFireStorage(
File(image.path), context);
images.removeLast();
images.add(imageUrl.url);
user.photos = images;
User newUser =
await FireStoreUtils.updateCurrentUser(user);
MyAppState.currentUser = newUser;
user = newUser;
images.add(null);
setState(() {});
}
},
)
],
cancelButton: CupertinoActionSheetAction(
child: Text("Cancel"),
onPressed: () {
Navigator.pop(context);
},
),
);
showCupertinoModalPopup(context: context, builder: (context) => action);
}
//here is the code in question
_pickAudio() {
final action = CupertinoActionSheet(
message: Text(
"Add Audio",
style: TextStyle(fontSize: 15.0),
),
actions: <Widget>[
CupertinoActionSheetAction(
child: Text("Choose from Files"),
isDefaultAction: false,
File file;// error is here
//on file choose button call this
try {
f = await FilePicker.getFile(
type: FileType.audio,
);
setState(() {
});
}catch(e){
//handle exception
}}
onPressed:(){
upload(file);
}
upload(File fil)async{
String fileName = fil.path
.split('/')
.last;
StorageReference firebaseStorageRef =
FirebaseStorage.instance.ref().child('uploads/$fileName');
StorageUploadTask uploadTask = firebaseStorageRef.putFile(fil);
StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;
taskSnapshot.ref.getDownloadURL().then(
(value) {
});
}
),
],
cancelButton: CupertinoActionSheetAction(
child: Text("Cancel"),
onPressed: () {
Navigator.pop(context);
},
),
);
showCupertinoModalPopup(context: context, builder: (context) => action);
}
#override
void dispose() {
_currentPageNotifier.dispose();
super.dispose();
}
}
any help would be amazing
thanks in advance!!!