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.
Related
Now I want to change the color of the bottom OverView (which has balck color initially and has three buttons home, back..) and I want the color from black to white. But I don't want to remove the SafeArea widget.
So I have an application that looks like this.
Here I have mentioned the code of my main.dart file. I have not done anything for Overview color but this code will give an understanding of what is happing.
main.dart
import 'package:Healthwise/pages/listPage.dart';
import 'package:Healthwise/pages/resultPage.dart';
import 'package:camera/camera.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:Healthwise/pages/home.dart';
import 'package:flutter/services.dart';
import 'package:get/get_navigation/src/root/get_material_app.dart';
List<CameraDescription>? cameras;
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
cameras = await availableCameras();
await Firebase.initializeApp();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
// We have removed the appbar
// appBarTheme: const AppBarTheme(
// systemOverlayStyle: SystemUiOverlayStyle(
// statusBarColor: Colors.white,
// statusBarBrightness: Brightness.light),
// ),
scaffoldBackgroundColor: Colors.white,
textSelectionTheme: const TextSelectionThemeData(
cursorColor: Color.fromARGB(255, 253, 126, 153),
selectionColor: Color.fromARGB(255, 253, 126, 153),
selectionHandleColor: Color.fromARGB(255, 253, 126, 153),
),
),
home: Home());
}
}
home.dart
import 'package:Healthwise/pages/listPage.dart';
import 'package:Healthwise/pages/resultPage.dart';
import 'package:Healthwise/helpers/user.dart';
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:Healthwise/main.dart';
import 'package:flutter/services.dart';
import 'package:tflite/tflite.dart';
import '../helpers/frontEnd.dart';
class Home extends StatefulWidget {
const Home({Key? key}) : super(key: key);
#override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
bool isWorking = false;
String result = '';
CameraController? cameraController;
CameraImage? imgCamera;
initCamera() {
cameraController = CameraController(cameras![0], ResolutionPreset.max);
cameraController!.initialize().then((value) {
if (!mounted) {
print("Camera Not Mounted");
return;
} else {
setState(() {
cameraController!.startImageStream((imageFromStream) {
if (!isWorking) {
isWorking = true;
imgCamera = imageFromStream;
runModelOnStreamFrames();
}
});
});
}
});
}
loadModel() async {
await Tflite.loadModel(
model: 'assets/model_unquant.tflite',
labels: 'assets/labels.txt',
);
}
#override
void initState() {
super.initState();
loadModel();
}
#override
void dispose() async {
// TODO: implement dispose
super.dispose();
await Tflite.close();
await cameraController?.dispose();
}
runModelOnStreamFrames() async {
var racognitions = await Tflite.runModelOnFrame(
bytesList: imgCamera!.planes.map((plane) {
return plane.bytes;
}).toList(),
imageHeight: imgCamera!.height,
imageWidth: imgCamera!.width,
imageMean: 127.5,
imageStd: 127.5,
rotation: 90,
numResults: 1,
threshold: 0.1,
asynch: true,
);
racognitions!.forEach((response) {
var res = response['confidence'] as double;
if (res > 0.95) {
result = response['label'];
// +
// ' ' +
// (response['confidence'] as double).toStringAsFixed(2);
}
});
if (mounted) {
setState(() {
result;
});
}
isWorking = false;
}
#override
Widget build(BuildContext context) {
return AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle.light,
child: Scaffold(
resizeToAvoidBottomInset: false,
floatingActionButtonLocation:
FloatingActionButtonLocation.centerDocked,
floatingActionButton: imgCamera == null
? CameraOpeningButton()
: CloseCameraAndSearch(cameraController),
// appBar:
// AppBar(backgroundColor: primary_color, title: application_name),
body: SafeArea(
child: Stack(children: [
Container(
constraints: const BoxConstraints.expand(),
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/SVG/MainBackground.png"),
fit: BoxFit.fill),
),
),
Container(
// height: 560,
child: Container(
height: 650,
width: 360,
child: imgCamera == null
? Column(
children: [
const SizedBox(
height: 20,
),
SearchBar(),
const SizedBox(
height: 20,
),
Center(
child: Container(
height: 500,
width: 340,
decoration: const BoxDecoration(
color: Color(0xFFffffff),
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 2.0, // soften the shadow
spreadRadius: 2.0, //extend the shadow
)
],
),
child: Column(
children: [
Container(
height: 50,
width: double.infinity,
color: Color.fromARGB(255, 253, 126, 153),
child: Center(
child: Text(
"Banana",
style: TextStyle(
color: Color.fromARGB(
255, 255, 255, 255),
fontSize: 25,
),
),
),
),
Container(
child: Column(
children: [
Image.network(
'https://images.everydayhealth.com/images/diet-nutrition/all-about-bananas-nutrition-facts-health-benefits-recipes-and-more-rm-722x406.jpg?w=1110'),
Container(
margin: EdgeInsets.symmetric(
vertical: 30, horizontal: 30),
child: Text(
'"If you feel recurrent soreness of muscles after a workout, you may lack magnesium in your body. A magnesium-rich banana may help with muscle contraction and relaxation that increase lean muscle mass."',
style: TextStyle(
color: Color.fromARGB(
255, 80, 80, 80),
fontSize: 20,
),
),
)
],
),
)
],
),
)),
const SizedBox(
height: 20,
),
],
)
: AspectRatio(
aspectRatio: cameraController!.value.aspectRatio,
child: CameraPreview(cameraController!),
)),
),
]),
)
// body: Container(
// decoration: BoxDecoration(),
// child: Column(children: [
// Stack(
// children: [
// Center(
// child: Container(
// margin: EdgeInsets.only(top: 100.0),
// height: 220,
// width: 320,
// child: Container(),
// ),
// ),
// Center(
// child: TextButton(
// onPressed: () {
// initCamera();
// },
// child: Container(
// margin: EdgeInsets.only(top: 5),
// height: 550,
// width: 360,
// child: imgCamera == null
// ? Container(
// height: 550,
// width: 360,
// child: Icon(
// Icons.photo_camera_front,
// color: Colors.pink,
// size: 60,
// ),
// )
// : AspectRatio(
// aspectRatio:
// cameraController!.value.aspectRatio,
// child: CameraPreview(cameraController!),
// )),
// ),
// )
// ],
// ),
// Center(
// child: Container(
// color: primary_color,
// margin: EdgeInsets.only(top: 10.0),
// child: SingleChildScrollView(
// // controller: controller,
// child: Text(
// result,
// style: const TextStyle(
// backgroundColor: Colors.black87,
// fontSize: 10.0,
// color: Colors.white),
// textAlign: TextAlign.center,
// )),
// ),
// ),
// ElevatedButton(
// onPressed: () async {
// if (result != '') {
// await cameraController?.stopImageStream();
// await cameraController?.pausePreview();
// itemName = result.toString();
// print("--------------------------------------------");
// print(itemName);
// Navigator.of(context).pushReplacement(
// MaterialPageRoute(builder: (context) => ResultPage()));
// }
// },
// child: Container(
// child: Text("Next"),
// color: Colors.blue,
// ))
// ]),
// ),
),
);
}
Row CloseCameraAndSearch(CameraController? cameraController) =>
Row(children: [
//Camera Close
TextButton(
style: TextButton.styleFrom(foregroundColor: Colors.pink),
onPressed: () async {
await cameraController?.stopImageStream();
await cameraController?.pausePreview();
imgCamera = null;
setState(() {});
},
child: Image(
image: AssetImage('assets/SVG/CloseCamera.png'),
height: 60,
width: 60,
),
),
//Result
Spacer(),
Container(
color: primary_color,
child: SingleChildScrollView(
// controller: controller,
child: Text(
result,
style: const TextStyle(
backgroundColor: Colors.black87,
fontSize: 10.0,
color: Colors.white),
textAlign: TextAlign.center,
)),
),
//Camera Close Next Page
Spacer(),
TextButton(
style: TextButton.styleFrom(foregroundColor: Colors.pink),
onPressed: () async {
if (result != '') {
await cameraController?.stopImageStream();
await cameraController?.pausePreview();
itemName = result.toString();
print(itemName);
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) => ResultPage()));
}
},
child: Image(
image: AssetImage('assets/SVG/SearchFruitButton.png'),
height: 60,
width: 60,
),
)
]);
// Camera Open
TextButton CameraOpeningButton() {
return TextButton(
style: TextButton.styleFrom(foregroundColor: Colors.pink),
onPressed: () {
initCamera();
},
child: Image(
image: AssetImage('assets/SVG/CameraButton.png'),
height: 60,
width: 60,
),
);
}
//SearchBar
Container SearchBar() {
return Container(
height: 50,
width: 340,
padding: EdgeInsets.fromLTRB(20, 0, 10, 0),
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20)),
//
color: Color.fromARGB(255, 255, 255, 255),
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 2.0, // soften the shadow
spreadRadius: 2.0, //extend the shadow
)
],
),
child: Row(
children: [
Container(
height: 40,
width: 240,
child: TextField(
decoration: InputDecoration(
border: InputBorder.none, hintText: 'Search Pomegranate'),
),
),
Spacer(),
TextButton(
style: ButtonStyle(alignment: AlignmentDirectional.centerEnd),
onPressed: () => {result},
child: Icon(
Icons.search,
color: Color.fromARGB(255, 253, 126, 153),
),
)
],
),
);
}
}
Try to set a custom systemNavigationBar color
var mySystemTheme= SystemUiOverlayStyle.light
.copyWith(systemNavigationBarColor: Colors.green);
SystemChrome.setSystemUiOverlayStyle(mySystemTheme);
I am trying to make the color of the status bar look white. I have tried to use AnnotatedRegion<SystemUiOverlayStyle> with value: SystemUiOverlayStyle.light, but this is not doing anything the app remains as it was before.
Below I have attached the code of my home.dart for which I want the status bar color to be white and I have attached the code of main.dart. One to mention here is that I am not using any appbar. I have attached the screenshot of my current page.
main.dart
import 'package:Healthwise/pages/listPage.dart';
import 'package:Healthwise/pages/resultPage.dart';
import 'package:camera/camera.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:Healthwise/pages/home.dart';
import 'package:flutter/services.dart';
import 'package:get/get_navigation/src/root/get_material_app.dart';
List<CameraDescription>? cameras;
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
cameras = await availableCameras();
await Firebase.initializeApp();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
// We have removed the appbar
// appBarTheme: const AppBarTheme(
// systemOverlayStyle: SystemUiOverlayStyle(
// statusBarColor: Colors.white,
// statusBarBrightness: Brightness.light),
// ),
scaffoldBackgroundColor: Colors.white,
textSelectionTheme: const TextSelectionThemeData(
cursorColor: Color.fromARGB(255, 253, 126, 153),
selectionColor: Color.fromARGB(255, 253, 126, 153),
selectionHandleColor: Color.fromARGB(255, 253, 126, 153),
),
),
home: Home());
}
}
home.dart
import 'package:Healthwise/pages/listPage.dart';
import 'package:Healthwise/pages/resultPage.dart';
import 'package:Healthwise/helpers/user.dart';
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:Healthwise/main.dart';
import 'package:flutter/services.dart';
import 'package:tflite/tflite.dart';
import '../helpers/frontEnd.dart';
class Home extends StatefulWidget {
const Home({Key? key}) : super(key: key);
#override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
bool isWorking = false;
String result = '';
CameraController? cameraController;
CameraImage? imgCamera;
initCamera() {
cameraController = CameraController(cameras![0], ResolutionPreset.max);
cameraController!.initialize().then((value) {
if (!mounted) {
print("Camera Not Mounted");
return;
} else {
setState(() {
cameraController!.startImageStream((imageFromStream) {
if (!isWorking) {
isWorking = true;
imgCamera = imageFromStream;
runModelOnStreamFrames();
}
});
});
}
});
}
loadModel() async {
await Tflite.loadModel(
model: 'assets/model_unquant.tflite',
labels: 'assets/labels.txt',
);
}
#override
void initState() {
super.initState();
loadModel();
}
#override
void dispose() async {
// TODO: implement dispose
super.dispose();
await Tflite.close();
await cameraController?.dispose();
}
runModelOnStreamFrames() async {
var racognitions = await Tflite.runModelOnFrame(
bytesList: imgCamera!.planes.map((plane) {
return plane.bytes;
}).toList(),
imageHeight: imgCamera!.height,
imageWidth: imgCamera!.width,
imageMean: 127.5,
imageStd: 127.5,
rotation: 90,
numResults: 1,
threshold: 0.1,
asynch: true,
);
racognitions!.forEach((response) {
var res = response['confidence'] as double;
if (res > 0.95) {
result = response['label'];
// +
// ' ' +
// (response['confidence'] as double).toStringAsFixed(2);
}
});
if (mounted) {
setState(() {
result;
});
}
isWorking = false;
}
#override
Widget build(BuildContext context) {
return AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle.light,
child: Scaffold(
resizeToAvoidBottomInset: false,
floatingActionButtonLocation:
FloatingActionButtonLocation.centerDocked,
floatingActionButton: imgCamera == null
? CameraOpeningButton()
: CloseCameraAndSearch(cameraController),
// appBar:
// AppBar(backgroundColor: primary_color, title: application_name),
body: SafeArea(
child: Stack(children: [
Container(
constraints: const BoxConstraints.expand(),
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/SVG/MainBackground.png"),
fit: BoxFit.fill),
),
),
Container(
// height: 560,
child: Container(
height: 650,
width: 360,
child: imgCamera == null
? Column(
children: [
const SizedBox(
height: 20,
),
SearchBar(),
const SizedBox(
height: 20,
),
Center(
child: Container(
height: 500,
width: 340,
decoration: const BoxDecoration(
color: Color(0xFFffffff),
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 2.0, // soften the shadow
spreadRadius: 2.0, //extend the shadow
)
],
),
child: Column(
children: [
Container(
height: 50,
width: double.infinity,
color: Color.fromARGB(255, 253, 126, 153),
child: Center(
child: Text(
"Banana",
style: TextStyle(
color: Color.fromARGB(
255, 255, 255, 255),
fontSize: 25,
),
),
),
),
Container(
child: Column(
children: [
Image.network(
'https://images.everydayhealth.com/images/diet-nutrition/all-about-bananas-nutrition-facts-health-benefits-recipes-and-more-rm-722x406.jpg?w=1110'),
Container(
margin: EdgeInsets.symmetric(
vertical: 30, horizontal: 30),
child: Text(
'"If you feel recurrent soreness of muscles after a workout, you may lack magnesium in your body. A magnesium-rich banana may help with muscle contraction and relaxation that increase lean muscle mass."',
style: TextStyle(
color: Color.fromARGB(
255, 80, 80, 80),
fontSize: 20,
),
),
)
],
),
)
],
),
)),
const SizedBox(
height: 20,
),
],
)
: AspectRatio(
aspectRatio: cameraController!.value.aspectRatio,
child: CameraPreview(cameraController!),
)),
),
]),
)
// body: Container(
// decoration: BoxDecoration(),
// child: Column(children: [
// Stack(
// children: [
// Center(
// child: Container(
// margin: EdgeInsets.only(top: 100.0),
// height: 220,
// width: 320,
// child: Container(),
// ),
// ),
// Center(
// child: TextButton(
// onPressed: () {
// initCamera();
// },
// child: Container(
// margin: EdgeInsets.only(top: 5),
// height: 550,
// width: 360,
// child: imgCamera == null
// ? Container(
// height: 550,
// width: 360,
// child: Icon(
// Icons.photo_camera_front,
// color: Colors.pink,
// size: 60,
// ),
// )
// : AspectRatio(
// aspectRatio:
// cameraController!.value.aspectRatio,
// child: CameraPreview(cameraController!),
// )),
// ),
// )
// ],
// ),
// Center(
// child: Container(
// color: primary_color,
// margin: EdgeInsets.only(top: 10.0),
// child: SingleChildScrollView(
// // controller: controller,
// child: Text(
// result,
// style: const TextStyle(
// backgroundColor: Colors.black87,
// fontSize: 10.0,
// color: Colors.white),
// textAlign: TextAlign.center,
// )),
// ),
// ),
// ElevatedButton(
// onPressed: () async {
// if (result != '') {
// await cameraController?.stopImageStream();
// await cameraController?.pausePreview();
// itemName = result.toString();
// print("--------------------------------------------");
// print(itemName);
// Navigator.of(context).pushReplacement(
// MaterialPageRoute(builder: (context) => ResultPage()));
// }
// },
// child: Container(
// child: Text("Next"),
// color: Colors.blue,
// ))
// ]),
// ),
),
);
}
Row CloseCameraAndSearch(CameraController? cameraController) =>
Row(children: [
//Camera Close
TextButton(
style: TextButton.styleFrom(foregroundColor: Colors.pink),
onPressed: () async {
await cameraController?.stopImageStream();
await cameraController?.pausePreview();
imgCamera = null;
setState(() {});
},
child: Image(
image: AssetImage('assets/SVG/CloseCamera.png'),
height: 60,
width: 60,
),
),
//Result
Spacer(),
Container(
color: primary_color,
child: SingleChildScrollView(
// controller: controller,
child: Text(
result,
style: const TextStyle(
backgroundColor: Colors.black87,
fontSize: 10.0,
color: Colors.white),
textAlign: TextAlign.center,
)),
),
//Camera Close Next Page
Spacer(),
TextButton(
style: TextButton.styleFrom(foregroundColor: Colors.pink),
onPressed: () async {
if (result != '') {
await cameraController?.stopImageStream();
await cameraController?.pausePreview();
itemName = result.toString();
print(itemName);
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) => ResultPage()));
}
},
child: Image(
image: AssetImage('assets/SVG/SearchFruitButton.png'),
height: 60,
width: 60,
),
)
]);
// Camera Open
TextButton CameraOpeningButton() {
return TextButton(
style: TextButton.styleFrom(foregroundColor: Colors.pink),
onPressed: () {
initCamera();
},
child: Image(
image: AssetImage('assets/SVG/CameraButton.png'),
height: 60,
width: 60,
),
);
}
//SearchBar
Container SearchBar() {
return Container(
height: 50,
width: 340,
padding: EdgeInsets.fromLTRB(20, 0, 10, 0),
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20)),
//
color: Color.fromARGB(255, 255, 255, 255),
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 2.0, // soften the shadow
spreadRadius: 2.0, //extend the shadow
)
],
),
child: Row(
children: [
Container(
height: 40,
width: 240,
child: TextField(
decoration: InputDecoration(
border: InputBorder.none, hintText: 'Search Pomegranate'),
),
),
Spacer(),
TextButton(
style: ButtonStyle(alignment: AlignmentDirectional.centerEnd),
onPressed: () => {result},
child: Icon(
Icons.search,
color: Color.fromARGB(255, 253, 126, 153),
),
)
],
),
);
}
}
Wrap your Scaffold with SafeArea and give color to the status bar as below code
return AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle.light.copyWith(statusBarColor: Colors.white),
child: SafeArea(
child: Scaffold(
i have a list which contains list of images, i want to show these in my grid view builder if list if not empty other wise i just want to show static + symbol in my grid view builder.
it is my list
var otherPersonOfferList = <Inventory>[].obs;
and this is my grid view builder which i have extracted as a widget and using it in my screen
import 'package:bartermade/models/Get_Inventory.dart';
import 'package:bartermade/models/inventory.dart';
import 'package:bartermade/widgets/inventoryTile.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../controllers/inventoryController.dart';
class OfferGrid extends StatefulWidget {
OfferGrid(
{Key? key,
required this.list,
required this.modelSheetHeading,
required this.gestureState})
: super(key: key);
String modelSheetHeading;
List<Inventory> list;
bool gestureState;
#override
State<OfferGrid> createState() => _OfferGridState();
}
class _OfferGridState extends State<OfferGrid> {
InventoryController inventoryController = Get.find();
bool isDeleting = false;
#override
Widget build(BuildContext context) {
if (widget.gestureState == true
? (inventoryController.otherPersonOfferList == [] ||
inventoryController.otherPersonOfferList.length == 0 ||
inventoryController.otherPersonOfferList.isEmpty)
: (inventoryController.myOfferList == [] ||
inventoryController.myOfferList.length == 0 ||
inventoryController.myOfferList.isEmpty)) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: GestureDetector(
onTap: () {
showModalBottomSheet(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
context: context,
builder: (context) {
return InventoryTile(
modelSheetHeading: widget.modelSheetHeading,
list: widget.gestureState == true
? inventoryController.traderInventoryList
: inventoryController.myInventoryList1,
inventoryController: inventoryController,
gestureState: widget.gestureState);
});
},
child: Container(
height: 90,
width: 90,
decoration: BoxDecoration(border: Border.all(color: Colors.black)),
child: Icon(
Icons.add,
size: 35,
),
),
),
);
} else {
return GridView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: widget.list.length + 1,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
itemBuilder: (context, index) {
if (index == widget.list.length) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: GestureDetector(
onTap: () {
showModalBottomSheet(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
context: context,
builder: (context) {
return InventoryTile(
modelSheetHeading: widget.modelSheetHeading,
list: widget.gestureState == true
? inventoryController.traderInventoryList
: inventoryController.myInventoryList1,
inventoryController: inventoryController,
gestureState: widget.gestureState);
});
},
child: Container(
height: 30,
width: 30,
decoration:
BoxDecoration(border: Border.all(color: Colors.black)),
child: Icon(
Icons.add,
size: 35,
),
),
),
);
} else {
return Stack(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: GestureDetector(
onLongPress: () {
setState(() {
isDeleting = true;
});
},
onTap : (){
setState(() {
isDeleting = false;
});
},
child: CachedNetworkImage(
fit: BoxFit.cover,
height: 100,
width: 200,
imageUrl: // "https://asia-exstatic-vivofs.vivo.com/PSee2l50xoirPK7y/1642733614422/0ae79529ef33f2b3eb7602f89c1472b3.jpg"
"${widget.list[index].url}",
placeholder: (context, url) => Center(
child: CircularProgressIndicator(
color: Colors.grey,
),
),
errorWidget: (context, url, error) => Icon(Icons.error),
),
),
),
isDeleting == true
? Positioned(
right: 0,
top: 0,
child: CircleAvatar(
backgroundColor: Colors.red,
radius: 10,
child: Icon(
Icons.remove,
size: 14,
),
),
)
: SizedBox()
],
);
}
});
}
}
}
and this is my screen where is just want to check if my list is non empty then fill my grid view with images otherwise just show + sign in grid view
import 'package:bartermade/controllers/inventoryController.dart';
import 'package:bartermade/models/Get_Inventory.dart';
import 'package:bartermade/models/inventory.dart';
import 'package:bartermade/screens/chat/chatScreen.dart';
import 'package:bartermade/utils/app_colors.dart';
import 'package:bartermade/widgets/snackBar.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import '../../../../services/inventoryService.dart';
import '../../../../widgets/offerGrid.dart';
class OfferTradeScreen extends StatefulWidget {
String postUserId;
String postUserName;
OfferTradeScreen({
Key? key,
required this.postUserId,
required this.postUserName,
}) : super(key: key);
#override
State<OfferTradeScreen> createState() => _OfferTradeScreenState();
}
class _OfferTradeScreenState extends State<OfferTradeScreen> {
// TradeController tradeController = Get.put(TradeController());
InventoryController inventoryController = Get.put(InventoryController());
// GiftStorageService giftStorageService = GiftStorageService();
// GiftController giftController = Get.put(GiftController());
// ProfileController profileController = Get.put(ProfileController());
// TradeStorageService tradeStorageService = TradeStorageService();
// TradingService tradingService = TradingService();
// PreferenceService preferenceService = PreferenceService();
late List<Inventory> otherPersonList;
late List<Inventory> myList;
#override
void initState() {
super.initState();
inventoryController.getOtherUserInventory(widget.postUserId);
otherPersonList = inventoryController.otherPersonOfferList;
myList = inventoryController.myOfferList;
}
otherPersonlistener() {
inventoryController.otherPersonOfferList.listen((p0) {
if (this.mounted) {
setState(() {
otherPersonList = p0;
});
}
});
}
mylistener() {
inventoryController.myOfferList.listen((p0) {
if (this.mounted) {
setState(() {
myList = p0;
});
}
});
}
int draggableIndex = 0;
#override
Widget build(BuildContext context) {
print("-------building------");
otherPersonlistener();
mylistener();
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
return Scaffold(
appBar: AppBar(
titleSpacing: 0,
leading: GestureDetector(
onTap: () {
inventoryController.myOfferList.clear();
inventoryController.otherPersonOfferList.clear();
Get.back();
},
child: Icon(Icons.arrow_back)),
title: Text(
"Offer",
style: TextStyle(color: Colors.white),
),
actions: [
Padding(
padding: const EdgeInsets.only(right: 15),
child: GestureDetector(
onTap: () {
Get.to(() => ChatScreen(
currentUserId: widget.postUserId,
recieverId: inventoryController.userId.toString()));
},
child: Icon(Icons.message)),
)
],
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
flex: 10,
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(top: 20),
child: Text(
"${widget.postUserName} Inventory",
style: TextStyle(
color: Colors.black,
fontSize: 20,
fontWeight: FontWeight.w400),
),
),
OfferGrid(
gestureState: true,
list: otherPersonList,
modelSheetHeading: "${widget.postUserName}",
)
],
),
),
),
Expanded(
flex: 1,
child: Divider(
thickness: 2,
color: Colors.black,
height: 3,
),
),
Expanded(
flex: 10,
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"My Inventory",
style: TextStyle(
color: Colors.black,
fontSize: 20,
fontWeight: FontWeight.w400),
),
OfferGrid(
gestureState: false,
list: myList,
modelSheetHeading: "My Inventory",
)
],
),
),
),
Center(child: Obx(() {
return inventoryController.makingOffer.value == true
? CircularProgressIndicator(
color: AppColors.pinkAppBar,
)
: ElevatedButton(
onPressed: () {
if (inventoryController.otherPersonOfferList.isEmpty &&
inventoryController.myOfferList.isEmpty) {
showSnackBar(
"Please add both inventories to make offer",
context);
} else {
inventoryController.postOffer(
widget.postUserId, context);
}
},
style: ElevatedButton.styleFrom(
padding: EdgeInsets.symmetric(
vertical: 10, horizontal: 50)),
child: Text("Send Offer"));
}))
],
),
),
);
}
#override
void dispose() {
SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeRight,
DeviceOrientation.landscapeLeft,
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
super.dispose();
}
}
User following code :
GridView.builder(
shrinkWrap: true,
itemCount: data.length,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 17,
mainAxisSpacing: 17,
),
itemBuilder: (
context,
index,
) {
return Obx(
() => InkWell(
onTap: () {
},
child: ClipRRect(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
border: Border.all(
color: ColorConfig.colorDarkBlue, width: 2),
image: DecorationImage(
image: AssetImage(ImagePath.unselectedContainer), ///imageURL
fit: BoxFit.fill,
)),
child: Center(
child: Text(data[index].heading,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: ThemeConstants.textThemeFontSize18,
fontWeight: FontWeight.w700,
color: ColorConfig.colorDarkBlue)),
),
height: 150,
),
),
),
);
},
),
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!!!