Flutter: SharedPreferences showing null value? - flutter

eg: details about the questions ............................................................................................i have set a address in home page using SharedPreferences but when i get that value in SearchModulePage showing null. i have tried many more times always showing null
Home Page:-
import 'dart:convert';
import 'dart:io';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:double_back_to_close_app/double_back_to_close_app.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:geocoder/geocoder.dart';
import 'package:http/http.dart' as http;
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:newbharatbiz/Model%20Class/category_model.dart';
import 'package:newbharatbiz/Screens/SearchServiceProvider.dart';
import 'package:newbharatbiz/Screens/SubCategoryPage.dart';
import 'package:newbharatbiz/Utils/NavDrawer.dart';
import 'package:newbharatbiz/Utils/Serverlinks.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../Model Class/banner_model.dart';
import 'VendorRegistrationPage.dart';
import 'package:location/location.dart';
import 'package:flutter/services.dart';
var addressLine;
var getaddressLine;
var androidDeviceInfo;
var token;
var identifier;
var user_id;
var phone;
var name;
class HomePage extends StatefulWidget {
#override
_YourWidgetState createState() => _YourWidgetState();
}
class _YourWidgetState extends State<HomePage> {
Future<BannerModel> BannerList() async {
final response = await http.get(Uri.parse(Serverlinks.all_banner));
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
print(response);
return BannerModel.fromJson(jsonDecode(response.body));
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load album');
}
}
Future<CategoryModel> CategoryList() async {
final response = await http.get(Uri.parse(Serverlinks.category_list));
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
print(response);
return CategoryModel.fromJson(jsonDecode(response.body));
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load album');
}
}
// late DateTime currentBackPressTime;
List<String> imagesList = [];
var currentLocation;
int currentIndexPage = 0;
#override
void initState() {
super.initState();
getUserLocation();
getdeviceid();
gettoken();
Setsharedpreferencevalue();
Getsharedpreferencevalue();
}
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.deepOrangeAccent,
child: Icon(Icons.add),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => VendorRegistrationPage(),
),
);
},
),
drawer: NavDrawer(),
appBar:
AppBar(title: Text('New Bharat Biz'), centerTitle: true, actions: [
IconButton(
onPressed: () async {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SearchServiceProvider(),
),
);
},
icon: Icon(Icons.search),
),
]),
body: DoubleBackToCloseApp(
child: SingleChildScrollView(
child: Column(mainAxisAlignment: MainAxisAlignment.start, children: [
FutureBuilder<BannerModel>(
future: BannerList(),
builder: (BuildContext context, snapshot) {
if (snapshot.hasData) {
print((snapshot.data));
snapshot.data!.banner.forEach((e) {
imagesList.add(snapshot.data!.imgPath + e.image);
print(imagesList.length);
});
return CarouselSlider(
//add return keyword here
options: CarouselOptions(
height: 160,
aspectRatio: 16 / 9,
viewportFraction: 0.8,
initialPage: 0,
enableInfiniteScroll: true,
reverse: false,
autoPlay: true,
autoPlayInterval: const Duration(seconds: 3),
autoPlayAnimationDuration:
const Duration(milliseconds: 800),
autoPlayCurve: Curves.fastOutSlowIn,
enlargeCenterPage: true,
),
items: imagesList
.map(
(item) => Center(
child: Image.network(item,
fit: BoxFit.cover, width: 1000)),
)
.toList(),
);
}
return const Center(
/*
child: SizedBox(
width: 16,
height: 16,
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor: AlwaysStoppedAnimation(Colors.blue),
),
),
*/
);
}
// By default, show a loading spinner.
),
FutureBuilder<CategoryModel>(
future: CategoryList(),
builder: (BuildContext context, snapshot) {
//_getId();
if (snapshot.hasData) {
List<Result> data = snapshot.data!.result;
print((snapshot.data));
return GridView.builder(
itemCount: data.length,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 0,
mainAxisSpacing: 0,
),
//padding: EdgeInsets.all(1),
itemBuilder: (ctx, index) {
return Padding(
padding: EdgeInsets.all(0.0),
child: new GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SubCategoryPage(
data[index].id,
),
),
);
},
child: new Container(
margin: const EdgeInsets.all(0),
padding: const EdgeInsets.all(0),
decoration: BoxDecoration(
border: Border.all(
width: 0.5,
color: Colors.grey,
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 25,
),
Image.network(
snapshot.data!.imgPath + data[index].coverPic,
height: 55,
width: 55,
),
SizedBox(
height: 10,
),
Expanded(
child: Text(
data[index].name,
style: TextStyle(
color: Colors.black,
fontSize: 15,
),
textAlign: TextAlign.center,
),
)
],
),
),
),
);
},
);
} else {
return const Center(
child: SizedBox(
width: 16,
height: 16,
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor: AlwaysStoppedAnimation(Colors.blue),
),
),
);
}
},
),
]),
),
snackBar: const SnackBar(
content: Text('Tap back again to leave'),
),
),
);
}
/*
Future<bool> onWillPop() {
DateTime now = DateTime.now();
if (currentBackPressTime == null ||
now.difference(currentBackPressTime) > Duration(seconds: 2)) {
currentBackPressTime = now;
return Future.value(false);
}
return Future.value(true);
}
*/
void getUserLocation() async {
//call this async method from whereever you need
LocationData? myLocation;
String error;
Location location = new Location();
try {
myLocation = await location.getLocation();
} on PlatformException catch (e) {
if (e.code == 'PERMISSION_DENIED') {
error = 'please grant permission';
print(error);
}
if (e.code == 'PERMISSION_DENIED_NEVER_ASK') {
error = 'permission denied- please enable it from app settings';
print(error);
}
myLocation = null;
}
currentLocation = myLocation;
final coordinates =
new Coordinates(myLocation?.latitude, myLocation?.longitude);
var addresses =
await Geocoder.local.findAddressesFromCoordinates(coordinates);
var first = addresses.first;
String adminArea = first.adminArea;
String locality = first.locality;
String subLocality = first.subLocality;
String subAdminArea = first.subAdminArea;
addressLine = first.addressLine;
String featureName = first.featureName;
String thoroughfare = first.thoroughfare;
String subThoroughfare = first.subThoroughfare;
/* print(' ${first.locality}, ${first.adminArea},${first.subLocality}, ${first.subAdminArea},${first.addressLine}, ${first.featureName},${first.thoroughfare}, ${first.subThoroughfare}');
return first;*/
}
gettoken() async {
//token = await FirebaseMessaging.instance.getToken();
FirebaseMessaging.instance.getToken().then((token) {
token = token.toString();
// do whatever you want with the token here
});
}
getdeviceid() async {
final DeviceInfoPlugin deviceInfoPlugin = new DeviceInfoPlugin();
if (Platform.isAndroid) {
AndroidDeviceInfo androidInfo = await deviceInfoPlugin.androidInfo;
androidDeviceInfo = androidInfo.id!; //UUID for Android
} else if (Platform.isIOS) {
IosDeviceInfo iosInfo = await deviceInfoPlugin.iosInfo;
androidDeviceInfo = iosInfo.identifierForVendor; //UUID for Android
}
}
void Setsharedpreferencevalue() async {
setState(() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setString('addressLine', addressLine);
prefs.setString('deviceID', androidDeviceInfo);
await prefs.setString("token", token!);
});
}
void Getsharedpreferencevalue() async {
setState(() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
androidDeviceInfo = prefs.getString('deviceID');
getaddressLine = prefs.getString('addressLine');
token = prefs.getString('token');
user_id = prefs.getString('user_id');
phone = prefs.getString('phone');
name = prefs.getString('name');
print("info : ${androidDeviceInfo}");
});
}
}
SearchModulePage:-
import 'dart:convert';
import 'package:flutter_mapbox_autocomplete/flutter_mapbox_autocomplete.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'package:newbharatbiz/Screens/SubCategoryPage.dart';
import 'package:shared_preferences/shared_preferences.dart';
var addressLine;
TextEditingController Locality = TextEditingController();
class SearchModulePage extends StatefulWidget {
String id;
String catId;
String serviceName;
String image;
String imgPath;
SearchModulePage(
this.id, this.catId, this.serviceName, this.image, this.imgPath);
#override
_YourWidgetState createState() =>
_YourWidgetState(id, catId, serviceName, image, imgPath);
}
class _YourWidgetState extends State<SearchModulePage> {
String id;
String catId;
String serviceName;
String image;
String imgPath;
_YourWidgetState(
this.id, this.catId, this.serviceName, this.image, this.imgPath);
#override
void initState() {
super.initState();
getshareddprefernces();
}
#override
Widget build(BuildContext context) {
// getsharedprefernces();
return WillPopScope(
onWillPop: () async => true,
child: new Scaffold(
appBar: new AppBar(
title: new Text(serviceName),
leading: new IconButton(
icon: new Icon(Icons.arrow_back_outlined),
onPressed: () {
Navigator.pop(
context, true); // It worked for me instead of above line
/* Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => SubCategoryPage(
catId,
)),
);*/
}),
),
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
const SizedBox(height: 30),
Image.network(
imgPath + image,
width: 60.0,
height: 60.0,
),
// Padding(padding: EdgeInsets.only(top: 15.0)),
const SizedBox(height: 20),
Text(serviceName,
style: TextStyle(color: Colors.black, fontSize: 15)),
// Padding(padding: EdgeInsets.only(top: 30.0)),
const SizedBox(height: 10),
Padding(
padding: const EdgeInsets.all(20.0),
child: TextFormField(
controller: Locality,
readOnly: true,
// initialValue: addressLine,
// set it to a string by default
decoration: InputDecoration(
hintText: "Search your locality",
hintStyle: TextStyle(
color: Color(0xff323131),
),
suffixIcon: Icon(
Icons.location_on_rounded,
color: Color(0xFF00796B),
),
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MapBoxAutoCompleteWidget(
apiKey:
"pk.eyJ1IjoibmV3YmhhcmF0Yml6IiwiYSI6ImNrbWJqb3B5ZzIyZnUyd254M2JndmhnNnQifQ.Km7hMjBHD_kwHWL7x7Y-Jg",
hint: "Search your locality",
onSelect: (place) {
// TODO : Process the result gotten
Locality.text = place.placeName!;
},
limit: 10,
),
),
);
},
),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
// FocusScope.of(context).requestFocus(FocusNode());
addressLine = Locality.text;
if (addressLine == "") {
Fluttertoast.showToast(
msg: "Enter your locality",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.black54,
textColor: Colors.white,
fontSize: 16.0);
/* var snackBar = SnackBar(content: Text('Enter your locality'));
ScaffoldMessenger.of(context).showSnackBar(snackBar);*/
} else {
// String locality = Locality.text;
}
},
child: Text("Submit"),
style: ElevatedButton.styleFrom(
primary: Color(0xFF00796B),
padding:
EdgeInsets.symmetric(horizontal: 100, vertical: 10),
textStyle:
TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
),
],
),
),
),
);
}
void getshareddprefernces() async {
setState(() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
addressLine = await prefs.getString('addressLine');
Locality.text = addressLine.toString();
Fluttertoast.showToast(
msg: addressLine,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.black54,
textColor: Colors.white,
fontSize: 16.0);
});
}
}

You have to wait till all asynchronous process is over, then after that when all values (here address, deviceId and token) are set to variables, then you can save or set values to shared preferences.
Here is the sample code for you:
#override
void initState() {
super.initState();
initializeVariables().then((boolValue){
Setsharedpreferencevalue();
});
// ..
}
Future<Boolean> initializeVariables() async {
await getUserLocation();
await getdeviceid();
await gettoken();
return true;
}

Related

Why does Flutter Camera Plugin return video content type as Application/octet-stream

hello guys!
i am using flutter story view package to implement story functionality in my app and i am using camera plugin to record video and upload, however the content type of the uploaded video is application/octet-stream when i receive it on my server and only when it is sent from ios. for android everything is fine and i get the content type as video/mp4.
can you guys please help me.
i have not done anything fancy i have just used the basic functionality of start recording and stop recording of the camra plugin.
// ignore_for_file: use_build_context_synchronously
List<CameraDescription>? cameras;
class CameraScreen extends StatefulWidget {
const CameraScreen({Key? key}) : super(key: key);
#override
State<CameraScreen> createState() => _CameraScreenState();
}
class _CameraScreenState extends State<CameraScreen> {
CameraController? _cameraController;
Future<void>? cameraValue;
bool flash = false;
bool iscamerafront = true;
static const _maxSeconds = 30;
ValueNotifier<bool> visible = ValueNotifier(false);
ValueNotifier<bool> isRecoring = ValueNotifier(false);
TimerProvider? _timerProvider;
#override
void initState() {
super.initState();
_timerProvider = Provider.of(context, listen: false);
_cameraController = CameraController(cameras![0], ResolutionPreset.veryHigh,
imageFormatGroup: ImageFormatGroup.bgra8888);
cameraValue = _cameraController?.initialize();
_cameraController?.prepareForVideoRecording();
lockCamera();
}
lockCamera() async {
await _cameraController!.lockCaptureOrientation();
}
#override
void dispose() {
super.dispose();
visible.dispose();
isRecoring.dispose();
_cameraController?.dispose();
}
#override
Widget build(BuildContext context) {
print("camera_screen");
final size = MediaQuery.of(context).size;
return Scaffold(
extendBodyBehindAppBar: true,
appBar: AppBar(
centerTitle: true,
title: ValueListenableBuilder<bool>(
valueListenable: visible,
builder: (context, value, child) {
return Visibility(
visible: value,
child: Container(
padding: const EdgeInsets.all(10),
width: 50,
height: 50,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.black.withOpacity(0.5)),
child: Center(
child: Consumer<TimerProvider>(
builder: (context, value, child) {
if (value.seconds == 0) {
if (_cameraController!.value.isRecordingVideo) {
stopRecording();
}
}
return Text(
value.seconds.toString(),
style: CustomStyles.fixAppBarTextStyle
.copyWith(color: Colors.white),
);
}),
),
));
}),
backgroundColor: Colors.transparent,
leadingWidth: 100,
leading: InkWell(
onTap: () {
Navigator.pop(context);
},
child: Center(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"Cancel",
style: CustomStyles.fixMediumBodyTextStyle
.copyWith(color: Colors.white),
),
)),
),
),
body: SafeArea(
top: false,
child: Stack(
children: [
FutureBuilder(
future: cameraValue,
builder: (context, snapshot) {
_cameraController?.lockCaptureOrientation();
if (snapshot.connectionState == ConnectionState.done) {
return Transform.scale(
scale: size.aspectRatio *
_cameraController!.value.aspectRatio <
1
? 1 /
(size.aspectRatio *
_cameraController!.value.aspectRatio)
: size.aspectRatio *
_cameraController!.value.aspectRatio,
child: Center(child: CameraPreview(_cameraController!)),
);
} else {
return const Center(
child: CircularProgressIndicator.adaptive(),
);
}
}),
Positioned(
bottom: 0.0,
child: Container(
padding: const EdgeInsets.only(top: 5, bottom: 5),
width: Dimensions.screenWidth,
child: Column(
children: [
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
padding: const EdgeInsets.all(4),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.black.withOpacity(0.5)),
child: Center(
child: IconButton(
icon: Icon(
flash ? Icons.flash_on : Icons.flash_off,
color: Colors.white,
size: 28,
),
onPressed: () {
setState(() {
flash = !flash;
});
flash
? _cameraController!
.setFlashMode(FlashMode.torch)
: _cameraController!
.setFlashMode(FlashMode.off);
}),
),
),
ValueListenableBuilder<bool>(
valueListenable: isRecoring,
builder: (context, value, child) {
return GestureDetector(
onLongPress: () {
startRecording();
},
onLongPressUp: () {
stopRecording();
},
onTap: () {
if (value == false) {
takePhoto(context);
}
},
child: value == true
? const CircleAvatar(
radius: 50,
backgroundColor: Colors.white30,
child: CircleAvatar(
radius: 35,
backgroundColor: Colors.red,
),
)
: const CircleAvatar(
radius: 35,
backgroundColor: Colors.white30,
child: CircleAvatar(
radius: 25,
backgroundColor: Colors.white,
),
));
}),
Container(
padding: const EdgeInsets.all(4),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.black.withOpacity(0.5)),
child: IconButton(
icon: const Icon(
Icons.flip_camera_ios,
color: Colors.white,
size: 28,
),
onPressed: () async {
setState(() {
iscamerafront = !iscamerafront;
});
int cameraPos = iscamerafront ? 0 : 1;
_cameraController = CameraController(
cameras![cameraPos], ResolutionPreset.high);
cameraValue = _cameraController?.initialize();
}),
),
],
),
addVerticalSpace(6),
const Text(
"Hold for Video, tap for photo",
style: TextStyle(
color: Colors.white,
),
textAlign: TextAlign.center,
),
addVerticalSpace(5),
],
),
),
),
],
),
),
);
}
void startRecording() async {
visible.value = true;
_timerProvider?.startCountDown(_maxSeconds);
isRecoring.value = true;
await _cameraController?.startVideoRecording();
}
void stopRecording() async {
XFile videopath = await _cameraController!.stopVideoRecording();
_timerProvider?.stopTimer();
isRecoring.value = false;
Navigator.push(
context,
MaterialPageRoute(
builder: (builder) => CameraResult(
image: File(videopath.path),
isImage: false,
))).then((value) {
visible.value = false;
});
}
void takePhoto(BuildContext context) async {
XFile file = await _cameraController!.takePicture();
SystemSound.play(SystemSoundType.click);
final img.Image? capturedImage =
img.decodeImage(await File(file.path).readAsBytes());
final img.Image orientedImage = img.flipHorizontal(capturedImage!);
File finalImage =
await File(file.path).writeAsBytes(img.encodeJpg(orientedImage));
Navigator.push(
context,
CupertinoPageRoute(
builder: (builder) => CameraResult(
image: finalImage,
isImage: true,
))).then((value) {
visible.value = false;
});
}
}
the upload function is as bellow
{File? shouts,
File? thumbnail,
int? duration,
bool? isImage,
required String userId,
required OnUploadProgressCallback onUploadProgress}) async {
assert(shouts != null);
try {
var url = Constants.POSTSHOUTURL;
final httpClient = FileService.getHttpClient();
final request = await httpClient.postUrl(Uri.parse(url));
int byteCount = 0;
var multipart;
if (isImage == false) {
multipart = await http.MultipartFile.fromPath(
'story-media', shouts!.path,
contentType: MediaType("video", "mp4"));
} else {
multipart = await http.MultipartFile.fromPath(
'story-media',
shouts!.path,
);
}
var multipart2 =
await http.MultipartFile.fromPath('thumbnail', thumbnail!.path);
var requestMultipart = http.MultipartRequest('POST', Uri.parse(url));
requestMultipart.fields["userid"] = userId.toString();
requestMultipart.fields["duration"] = duration.toString();
requestMultipart.headers['Content-type'] = 'multipart/form-data';
requestMultipart.files.add(multipart);
requestMultipart.files.add(multipart2);
var msStream = requestMultipart.finalize();
var totalByteLength = requestMultipart.contentLength;
request.contentLength = totalByteLength;
request.headers.add(HttpHeaders.authorizationHeader,
"Bearer ${Hive.box<UserData>(Constants.userDb).get(Hive.box<UserData>(Constants.userDb).keyAt(0))!.token}");
request.headers.set(HttpHeaders.contentTypeHeader,
requestMultipart.headers[HttpHeaders.contentTypeHeader]!);
Stream<List<int>> streamUpload = msStream.transform(
StreamTransformer.fromHandlers(
handleData: (data, sink) {
sink.add(data);
byteCount += data.length;
if (onUploadProgress != null) {
onUploadProgress(byteCount, totalByteLength);
// CALL STATUS CALLBACK;
}
},
handleError: (error, stack, sink) {
throw error;
},
handleDone: (sink) {
sink.close();
// UPLOAD DONE;
},
),
);
await request.addStream(streamUpload);
final httpResponse = await request.close();
var statusCode = httpResponse.statusCode;
if (statusCode ~/ 100 == 2) {
onUploadProgress(0, 0);
return await FileService.readResponseAsString(httpResponse);
}
return "";
} on SocketException {
throw FetchDataException("No internet to upload Shout!");
}
}```
i have used necessary info.plist setting also

How to deal with infinite size

I was coding my flutter project when I fall under this error. I do not understand because I have tried all the available solution online and still it is not working. The craziest thing is I have the exact same code on the other page and it is working perfectly.
And If I restart the app it works. The first problem was a Material app which is the main function and even if I wrap the column with a scaffold it still doesn't work
Below is the error
The following assertion was thrown during performLayout():
RenderCustomMultiChildLayoutBox object was given an infinite size during layout.
This probably means that it is a render object that tries to be as big as possible, but it was put inside another render object that allows its children to pick their own size.
The nearest ancestor providing an unbounded height constraint is: _RenderSingleChildViewport#20590 relayoutBoundary=up10 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
... needs compositing
... parentData: <none> (can use size)
... constraints: BoxConstraints(w=358.0, 0.0<=h<=731.0)
... layer: OffsetLayer#17148
... engine layer: OffsetEngineLayer#48e1c
... handles: 2
... offset: Offset(16.0, 63.0)
... size: Size(358.0, 731.0)
The constraints that applied to the RenderCustomMultiChildLayoutBox were: BoxConstraints(0.0<=w<=358.0, 0.0<=h<=Infinity)
The exact size it was given was: Size(358.0, Infinity)
Below this I have form that receives data from another one
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:loading_overlay/loading_overlay.dart';
import 'package:tembea/components/rounded_button.dart';
import 'package:tembea/components/show_toast.dart';
import 'package:tembea/components/time_pick.dart';
import 'package:tembea/screens/admin/admin_screens/restaurant/dashboard_restaurant.dart';
import '../../../../../constants.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:tembea/components/square_button.dart';
import 'dart:io' ;
import 'package:firebase_storage/firebase_storage.dart';
import 'add_images.dart';
class RestaurantSecondaryForm extends StatefulWidget {
const RestaurantSecondaryForm({
Key? key,
required this.name,
required this.location,
required this.price,
required this.description,
}) : super(key: key);
final String name;
final String location;
final String price;
final String description;
#override
_RestaurantSecondaryFormState createState() => _RestaurantSecondaryFormState();
}
class _RestaurantSecondaryFormState extends State<RestaurantSecondaryForm> {
bool showSpinner = false;
String selectedOpeningTime = '8:00 AM';
String selectedClosingTime = '17:00 PM';
String ? selectedTime;
final List<String> defaultImageList = [
'assets/images/image.png',
'assets/images/image.png',
'assets/images/image.png',
];
List<String> imageList =[];
List<File> files = [];
List<String> ? imageUrl;
TaskSnapshot? snap;
String ? photoUrl;
String ? photoUrl2;
String ? photoUrl3;
String selectedType = 'Restaurant';
#override
Widget build(BuildContext context) {
Future<void> openTimePicker(context) async {
final TimeOfDay? t =
await showTimePicker(
context: context, initialTime: TimeOfDay.now());
if(t != null){
setState(() {
selectedTime = t.format(context);
});
}
}
goToAddImage() async{
List<String> imgUrl = await Navigator.push(context, MaterialPageRoute(builder:(context){
return const AddImages();
}));
setState(() {
imageUrl = imgUrl;
});
}
if(imageUrl?.isNotEmpty == true){
setState(() {
photoUrl = imageUrl?[0];
photoUrl2 = imageUrl?[1];
photoUrl3 = imageUrl?[2];
imageList.add(photoUrl!);
imageList.add(photoUrl2!);
imageList.add(photoUrl3!);
});
}
else{
setState(() {
photoUrl = '';
photoUrl2 = '';
photoUrl3 = '';
});
}
return LoadingOverlay(
isLoading: showSpinner,
opacity: 0.5,
color: Colors.green,
progressIndicator: const CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation(Colors.green),
),
child: Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
title: const Text('Add Restaurant'),
backgroundColor: kBackgroundColor.withOpacity(0.3),
),
body: Padding(
padding: const EdgeInsets.all(40.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
CarouselSlider(
options: CarouselOptions(
enlargeCenterPage: true,
enableInfiniteScroll: false,
autoPlay: false,
),
items:imageList.isEmpty ? defaultImageList.map((e) => ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Stack(
fit: StackFit.expand,
children: [
Image.asset(
e,
width: 1000,
height: 300,
fit: BoxFit.fill,
)
],
),
)).toList()
: imageList.map((e) => ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Stack(
fit: StackFit.expand,
children: [
Image.network(
e,
width: 1000,
height: 300,
fit: BoxFit.fill,
)
],
),
)).toList(),
),
const SizedBox(
height: 20,
),
Column(
children: [
DateButton(
text: 'Upload Images',
onPressed: () {
goToAddImage();
},
),
],
),
Column(
children: [
TimePick(
label: 'Opens at',
labelColor: Colors.green,
time: selectedOpeningTime,
onPressed: (){
openTimePicker(context).then((value) {
setState(() {
selectedOpeningTime = selectedTime!;
});
});
},
),
const SizedBox(
height: 20,
),
TimePick(
label: 'Closes at',
labelColor: Colors.red,
time: selectedClosingTime,
onPressed: (){
openTimePicker(context).then((value) {
setState(() {
selectedClosingTime = selectedTime!;
});
});
}
),
],
),
RoundedButton(
buttonName: 'Add Restaurant',
color: Colors.green,
onPressed: () async{
setState(() {
showSpinner = true;
});
final time = DateTime.now();
await FirebaseFirestore.instance.collection('activities').doc().set({
'Name' : widget.name,
'Location': widget.location,
'Description' : widget.description,
'Price' : widget.price,
'OpeningTime' : selectedOpeningTime,
'ClosingTime' : selectedClosingTime,
'PhotoUrl' : photoUrl,
'PhotoUrl2' : photoUrl2,
'PhotoUrl3' : photoUrl3,
'Type' : selectedType,
'ts' : time,
}).then((value) {
setState(() {
showSpinner = false;
});
showToast(message: 'Restaurant Added',
color: Colors.green
);
Navigator.pushNamedAndRemoveUntil(context, DashboardRestaurant.id, (r) => false);
});
}
),
],
),
),
),
);
}
}
which is supposed to navigate back to this view that brings the error
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:tembea/components/add_button.dart';
import 'package:tembea/components/responsive.dart';
import 'package:tembea/components/show_dialog.dart';
import 'package:tembea/components/show_toast.dart';
import 'package:tembea/screens/admin/admin_screens/view_data.dart';
import 'event_form.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/foundation.dart';
class DashboardEvent extends StatefulWidget {
const DashboardEvent({Key? key}) : super(key: key);
static String id = 'dashboard_event';
#override
_DashboardEventState createState() => _DashboardEventState();
}
class _DashboardEventState extends State<DashboardEvent> {
final Stream<QuerySnapshot> activities = FirebaseFirestore
.instance.collection('activities')
.where('Type', isEqualTo: 'Event')
.orderBy('ts', descending: true)
.snapshots();
#override
Widget build(BuildContext context) {
return Column(
children: [
AddButton(
title: 'Events',
addLabel: 'Add Events',
onPressed: (){
Navigator.pushNamed(context, EventForm.id);
},),
const SizedBox(
height: 16.0,
),
const Divider(
color: Colors.white70,
height:40.0,
),
StreamBuilder<QuerySnapshot>(
stream: activities,
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot){
if(snapshot.connectionState == ConnectionState.waiting){
return const Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation(Colors.green),
),
);
}
final data = snapshot.requireData;
if(data != null){
return ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: data.size,
itemBuilder: (context, index){
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
CircleAvatar(
backgroundColor: Colors.transparent,
radius: 40,
child:Image.network(
data.docs[index]['PhotoUrl'],
),
),
Text( data.docs[index]['Name'], style:const TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold),
),
if(Responsive.isWeb(context))
const SizedBox(
width: 50,
),
Responsive.isWeb(context) ? ButtonBlue(
addLabel: 'View Event',
color: Colors.green,
onPressed: (){
Navigator.push(context, MaterialPageRoute(builder: (context){
return ViewData(item: data.docs[index],);
}));
},
icon: const Icon(IconData(61161, fontFamily: 'MaterialIcons')),
) : InkWell(
onTap: (){
Navigator.push(context, MaterialPageRoute(builder: (context){
return ViewData(item: data.docs[index],);
}));
},
child: const Icon(IconData(61161, fontFamily: 'MaterialIcons')),
),
Responsive.isWeb(context) ? ButtonBlue(
addLabel: 'Delete Event',
color: Colors.red,
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context){
return ShowDialog(
deleteFunction: () async{
await FirebaseFirestore.instance.runTransaction((Transaction myTransaction) async {
FirebaseStorage.instance.refFromURL(data.docs[index]['PhotoUrl']).delete();
myTransaction.delete(snapshot.data!.docs[index].reference);
}).then((value) => Navigator.pop(context));
},
dialogTitle: "Delete",
dialogContent: "Do you really want to delete ${data.docs[index]['Name']} event?",
);
});
},
icon: const Icon(Icons.delete_outline,),
): InkWell(
onTap: (){
if(defaultTargetPlatform == TargetPlatform.iOS){
showCupertinoDialog(
context: context,
builder: (BuildContext context){
return ShowDialog(
deleteFunction: () async{
await FirebaseFirestore.instance.runTransaction((Transaction myTransaction) async {
FirebaseStorage.instance.refFromURL(data.docs[index]['PhotoUrl']).delete();
myTransaction.delete(snapshot.data!.docs[index].reference);
}).then((value) => Navigator.pop(context));
},
dialogTitle: "Delete",
dialogContent: "Do you really want to delete ${data.docs[index]['Name']} event?",
);
});
}
else if((defaultTargetPlatform == TargetPlatform.android)){
showDialog(
context: context,
builder: (BuildContext context){
return ShowDialog(
deleteFunction: () async{
await FirebaseFirestore.instance.runTransaction((Transaction myTransaction) async {
FirebaseStorage.instance.refFromURL(data.docs[index]['PhotoUrl']).delete();
myTransaction.delete(snapshot.data!.docs[index].reference);
}).then((value) => Navigator.pop(context));
},
dialogTitle: "Delete",
dialogContent: "Do you really want to delete ${data.docs[index]['Name']} event?",
);
});
}
else{
showDialog(
context: context,
builder: (BuildContext context){
return ShowDialog(
deleteFunction: () async{
await FirebaseFirestore.instance.runTransaction((Transaction myTransaction) async {
FirebaseStorage.instance.refFromURL(data.docs[index]['PhotoUrl']).delete();
myTransaction.delete(snapshot.data!.docs[index].reference);
Navigator.pop(context);
showToast(message: 'Deleted Successfully', color: Colors.green);
}).then((value) => Navigator.pop(context));
},
dialogTitle: "Delete",
dialogContent: "Do you really want to delete ${data.docs[index]['Name']} event?",
);
});
}
},
child: const Icon(Icons.delete_outline,),
),
],
),
const Divider(
color: Colors.white70,
height:40.0,
),
],
);
});
}
return const Center(
child: CircularProgressIndicator(),
);
},
)
],
);
}
}
I have been on this the entire day but in vain but in the same product, I have another view details with the same code that works
Please assist me on this

RenderFlex children have non-zero flex but incoming height constraints are unbounded in flatter

I have a page code written in an android studio. On this page, I display a list of objects, as well as a widget to search for these objects. When I clicked on the search widget, I had the following problem: "The following statement was thrown during layout:
RenderFlex is overcrowded 31 pixels below.
The corresponding widget that caused the errors was: "But then I found the answer to this question and added" SingleChildScrollView ".
But then I had this problem: "RenderFlex have non-zero flexibility, but the input height limits are unlimited." . And I can't solve it in any way. I will be grateful for your help. Here is my code:
import 'package:flutter/material.dart';
import 'package:flutter_app_seals/model/post/form_unseals.dart';
import 'package:flutter_app_seals/model/post/form_seals.dart';
import 'package:flutter_app_seals/model/setting/globalvar.dart' as global;
import 'dart:async';
import 'dart:io';
import 'dart:convert';
void main() => runApp(JsonParseObjectSts_UN());
class JsonParseObjectSts_UN extends StatefulWidget {
JsonParseObjectSts_UN() : super();
#override
_JsonParseObjectsState createState() => _JsonParseObjectsState();
}
class _JsonParseObjectsState extends State <StatefulWidget> {
List<UserDetails> _searchResult = [];
List<UserDetails> _userDetails = [];
TextEditingController controller = new TextEditingController();
final String url = global.urlVar ;
// Get json result and convert it to model. Then add
Future<Null> getUserDetails() async {
HttpClient client = new HttpClient();
client.badCertificateCallback = ((X509Certificate cert, String host, int port) => true);
final request = await client
.getUrl(Uri.parse(url))
.timeout(Duration(seconds: 5));
HttpClientResponse response = await request.close();
var responseBody = await response.transform(utf8.decoder).join();
final responseJson = json.decode(responseBody);
setState(() {
for (Map user in responseJson) {
_userDetails.add(UserDetails.fromJson(user));
}
});
}
#override
void initState() {
super.initState();
getUserDetails();
}
Widget _buildUsersList() {
return new ListView.builder(
itemCount: _userDetails.length,
itemBuilder: (context, index) {
return new Card(
color: (_userDetails[index].sealed == "Так") ? Colors.redAccent : Colors.greenAccent,
margin: EdgeInsets.symmetric(vertical: 7),
child: ListTile(
title: Text(
_userDetails[index].name,
style: TextStyle(fontSize: 25),
),
subtitle: Text("Запломбований:${_userDetails[index].sealed}"),
leading: Icon(
Icons.home_outlined,
size: 30,
color: Colors.black87,
),
onTap: () =>
{
if ('Так' == _userDetails[index].sealed) {
global.nameObj = _userDetails[index].name,
global.sealsNumb = _userDetails[index].seal_number,
global.typesOp = 'Так',
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Unseals()),
)
}
else{
{
global.nameObj = _userDetails[index].name,
global.typesOp = 'Ні',
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Form_seals()),
)
}
}
}
),
);
},
);
}
Widget _buildSearchResults() {
return new ListView.builder(
itemCount: _searchResult.length,
itemBuilder: (context, i) {
return new Card(
color: (_searchResult[i].sealed == "Так") ? Colors.redAccent : Colors.greenAccent,
margin: EdgeInsets.symmetric(vertical: 7),
child: ListTile(
title: Text(
_searchResult[i].name,
style: TextStyle(fontSize: 25),
),
subtitle: Text("Запломбований:${_searchResult[i].sealed}"),
leading: Icon(
Icons.home_outlined,
size: 30,
color: Colors.black87,
),
onTap: () =>
{
if ('Так' == _searchResult[i].sealed) {
global.nameObj = _searchResult[i].name,
global.sealsNumb = _searchResult[i].seal_number,
global.typesOp = 'Так',
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Unseals()),
)
}
else{
{
global.nameObj = _searchResult[i].name,
global.typesOp = 'Ні',
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Form_seals()),
)
}
}
}
),
);
},
);
}
Widget _buildSearchBox() {
return new Padding(
padding: const EdgeInsets.all(8.0),
child: new Card(
child: new ListTile(
leading: new Icon(Icons.search),
title: new TextField(
controller: controller,
decoration: new InputDecoration(
hintText: 'Пошук', border: InputBorder.none),
onChanged: onSearchTextChanged,
),
trailing: new IconButton(
icon: new Icon(Icons.cancel),
onPressed: () {
controller.clear();
onSearchTextChanged('');
},
),
),
),
);
}
Widget _buildBody() {
return new Scaffold(
body:Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.blue, Colors.white],
begin: Alignment.topCenter,
end: Alignment.bottomCenter),
),
child: SingleChildScrollView(
child:Column(
children: <Widget>[
new Container(
color: Theme.of(context).primaryColor, child: _buildSearchBox()),
new Expanded(
child: _searchResult.length != 0 || controller.text.isNotEmpty
? _buildSearchResults()
: _buildUsersList()),
],
),
),
),
);
}
#override
Widget build(BuildContext context) {
return new Scaffold(
body: _buildBody()
);
}
onSearchTextChanged(String text) async {
_searchResult.clear();
if (text.isEmpty) {
setState(() {});
return;
}
_userDetails.forEach((userDetail) {
if (userDetail.name.contains(text) ) _searchResult.add(userDetail);
});
setState(() {});
}
}
class UserDetails {
final String name, seal_number,sealed;
UserDetails({this.name, this.sealed, this.seal_number});
factory UserDetails.fromJson(Map<String, dynamic> json) {
return new UserDetails(
sealed: json['sealed'],
name: json['name'],
seal_number: json['seal_number'],
);
}
}
My scrin:
My scrin when I want to use search:

how to increase the size of the window with the search result in flutter?

I have a page code written in an android studio. On this page, I display a list of objects, as well as a widget to search for these objects. When I clicked on the search widget,my list of objects is shrinking, and it is almost invisible (it is at the top). Can this be fixed somehow so that it can be seen on the whole page ??
import 'package:flutter/material.dart';
import 'package:flutter_app_seals/model/post/form_unseals.dart';
import 'package:flutter_app_seals/model/post/form_seals.dart';
import 'package:flutter_app_seals/model/setting/globalvar.dart' as global;
import 'dart:async';
import 'dart:io';
import 'dart:convert';
void main() => runApp(JsonParseObjectSts_UN());
class JsonParseObjectSts_UN extends StatefulWidget {
JsonParseObjectSts_UN() : super();
#override
_JsonParseObjectsState createState() => _JsonParseObjectsState();
}
class _JsonParseObjectsState extends State <StatefulWidget> {
List<UserDetails> _searchResult = [];
List<UserDetails> _userDetails = [];
TextEditingController controller = new TextEditingController();
final String url = global.urlVar ;
// Get json result and convert it to model. Then add
Future<Null> getUserDetails() async {
HttpClient client = new HttpClient();
client.badCertificateCallback = ((X509Certificate cert, String host, int port) => true);
final request = await client
.getUrl(Uri.parse(url))
.timeout(Duration(seconds: 5));
HttpClientResponse response = await request.close();
var responseBody = await response.transform(utf8.decoder).join();
final responseJson = json.decode(responseBody);
setState(() {
for (Map user in responseJson) {
_userDetails.add(UserDetails.fromJson(user));
}
});
}
#override
void initState() {
super.initState();
getUserDetails();
}
Widget _buildUsersList() {
return new ListView.builder(
itemCount: _userDetails.length,
itemBuilder: (context, index) {
return new Card(
color: (_userDetails[index].sealed == "Так") ? Colors.redAccent : Colors.greenAccent,
margin: EdgeInsets.symmetric(vertical: 7),
child: ListTile(
title: Text(
_userDetails[index].name,
style: TextStyle(fontSize: 25),
),
subtitle: Text("Запломбований:${_userDetails[index].sealed}"),
leading: Icon(
Icons.home_outlined,
size: 30,
color: Colors.black87,
),
onTap: () =>
{
if ('Так' == _userDetails[index].sealed) {
global.nameObj = _userDetails[index].name,
global.sealsNumb = _userDetails[index].seal_number,
global.typesOp = 'Так',
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Unseals()),
)
}
else{
{
global.nameObj = _userDetails[index].name,
global.typesOp = 'Ні',
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Form_seals()),
)
}
}
}
),
);
},
);
}
Widget _buildSearchResults() {
return new ListView.builder(
itemCount: _searchResult.length,
itemBuilder: (context, i) {
return new Card(
color: (_searchResult[i].sealed == "Так") ? Colors.redAccent : Colors.greenAccent,
margin: EdgeInsets.symmetric(vertical: 7),
child: ListTile(
title: Text(
_searchResult[i].name,
style: TextStyle(fontSize: 25),
),
subtitle: Text("Запломбований:${_searchResult[i].sealed}"),
leading: Icon(
Icons.home_outlined,
size: 30,
color: Colors.black87,
),
onTap: () =>
{
if ('Так' == _searchResult[i].sealed) {
global.nameObj = _searchResult[i].name,
global.sealsNumb = _searchResult[i].seal_number,
global.typesOp = 'Так',
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Unseals()),
)
}
else{
{
global.nameObj = _searchResult[i].name,
global.typesOp = 'Ні',
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Form_seals()),
)
}
}
}
),
);
},
);
}
Widget _buildSearchBox() {
return new Padding(
padding: EdgeInsets.all(7.0),
child: new Card(
child: new ListTile(
leading: new Icon(Icons.search),
title: new TextField(
controller: controller,
decoration: new InputDecoration(
hintText: 'Пошук', border: InputBorder.none),
onChanged: onSearchTextChanged,
),
trailing: new IconButton(
icon: new Icon(Icons.cancel),
onPressed: () {
controller.clear();
onSearchTextChanged('');
},
),
),
),
);
}
Widget _buildBody() {
return new Scaffold(
body:Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.blue, Colors.white],
begin: Alignment.topCenter,
end: Alignment.bottomCenter),
),
child:Column(
children: <Widget>[
new Expanded( flex: 1, child: _buildSearchBox()),
new Expanded(flex:8,
child: _searchResult.length != 0 || controller.text.isNotEmpty
? _buildSearchResults()
: _buildUsersList()),
],
),
),
);
}
#override
Widget build(BuildContext context) {
return new Scaffold(
body: _buildBody()
);
}
onSearchTextChanged(String text) async {
_searchResult.clear();
if (text.isEmpty) {
setState(() {});
return;
}
_userDetails.forEach((userDetail) {
if (userDetail.name.contains(text) ) _searchResult.add(userDetail);
});
setState(() {});
}
}
class UserDetails {
final String name, seal_number,sealed;
UserDetails({this.name, this.sealed, this.seal_number});
factory UserDetails.fromJson(Map<String, dynamic> json) {
return new UserDetails(
sealed: json['sealed'],
name: json['name'],
seal_number: json['seal_number'],
);
}
}
My page:
My page with search:
I have looked at your code several times, I just noticed a small error.
For the results of your searches, you try to display the "List" of searches in a ListView.builder, which is in a column in the parent container does not have a defined height.
Solution: Set a height for the main container and the problem will be solved

Flutter image_picker package returns null when trying to retrieve a video from the gallery

I am trying to build an app that lets users select videos and upload them, so for this, I am using the image_picker package. However, I am currently running tests and whenever I try to select a video from the gallery, instead of getting a file back I get null. I don't know if the problem is with how I am using the package or with permissions, although according to the package you don't need permissions for android.
Below the function in my code that is giving me trouble:
handleChooseFromGallery() async {
Navigator.pop(context);
File filePicked = await ImagePicker.pickVideo(
source: ImageSource.gallery,
maxDuration: Duration(seconds: 90),
);
//This line always returns false
print({'is file not null': filePicked != null});
setState(() {
if (filePicked != null) {
this.files.add(filePicked);
this.selected = true;
} else {
showError();
}
});
}
The complete code (minus completely irrelevant things):
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:golfapp/data/course_data.dart';
import 'package:golfapp/data/user_data.dart';
import 'package:provider/provider.dart';
import 'package:image_picker/image_picker.dart';
import 'package:uuid/uuid.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:golfapp/data/semana_data.dart';
import 'package:golfapp/widgets/chewie_item.dart';
final StorageReference storageRef = FirebaseStorage.instance.ref();
final postsRef = Firestore.instance.collection('posts');
final DateTime timestamp = DateTime.now();
class DetailScreen extends StatefulWidget {
final int index;
final String photoUrl;
final String videoUrl;
DetailScreen({this.index, this.photoUrl, this.videoUrl});
#override
_DetailScreenState createState() => _DetailScreenState();
}
class _DetailScreenState extends State<DetailScreen> {
bool isUploading = false;
bool selected = false;
List<File> files = [];
String postId = Uuid().v4();
TextEditingController captionController = TextEditingController();
showError() {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Row(
children: [
Padding(
padding: EdgeInsets.only(right: 10.0),
child: Text('Error'),
),
Icon(Icons.error_outline, size: 60.0),
],
),
content: SingleChildScrollView(
child: ListBody(
children: [
Text(
'Hubo un error con el video seleccionado.',
style: TextStyle(
fontFamily: 'Montserrat',
fontWeight: FontWeight.w600,
fontSize: 17.0,
),
),
],
),
),
);
},
);
}
clearImage() {
setState(() {
this.selected = false;
});
}
handleTakePhoto() async {
Navigator.pop(context);
File fileTaken = await ImagePicker.pickVideo(
source: ImageSource.camera,
maxDuration: Duration(seconds: 90),
);
setState(() {
if (fileTaken != null) {
this.files.add(fileTaken);
this.selected = true;
} else {
showError();
}
});
}
handleChooseFromGallery() async {
Navigator.pop(context);
File filePicked = await ImagePicker.pickVideo(
source: ImageSource.gallery,
maxDuration: Duration(seconds: 90),
);
print({'is file not null': filePicked != null});
setState(() {
if (filePicked != null) {
this.files.add(filePicked);
this.selected = true;
} else {
showError();
}
});
}
selectImage(parentContext) {
return showDialog(
context: parentContext,
builder: (context) {
return SimpleDialog(
title: Text("Seleccionar video"),
children: <Widget>[
SimpleDialogOption(
child: Text("Tomar video"),
onPressed: handleTakePhoto,
),
SimpleDialogOption(
child: Text("Video de la galería"),
onPressed: handleChooseFromGallery,
),
SimpleDialogOption(
child: Text("Cancelar"),
onPressed: () => Navigator.pop(context),
)
],
);
},
);
}
Future<String> uploadVideo(imageFile) async {
StorageUploadTask uploadTask = storageRef
.child(Provider.of<UserData>(context, listen: false).user.id)
.child(Provider.of<CourseData>(context, listen: false).course.uid)
.child(Provider.of<SemanaData>(context, listen: false).semana.uid)
.putFile(imageFile, StorageMetadata(contentType: 'video/mp4'));
StorageTaskSnapshot storageSnap = await uploadTask.onComplete;
String downloadUrl = await storageSnap.ref.getDownloadURL();
return downloadUrl;
}
createPostInFirestore({List<String> mediaUrl, String description}) {
postsRef
.document(Provider.of<UserData>(context, listen: false).user.id)
.collection("userPosts")
.document(Provider.of<CourseData>(context, listen: false).course.uid)
.setData({
"semana": Provider.of<SemanaData>(context, listen: false).semana.uid,
"postId": postId,
"ownerId": Provider.of<UserData>(context, listen: false).user.id,
"username": Provider.of<UserData>(context, listen: false).user.username,
"mediaUrl": mediaUrl,
"description": description,
"timestamp": timestamp,
"likes": {},
});
}
handleSubmit() async {
setState(() {
isUploading = true;
});
List<String> mediaUrlS = [];
for (File fileLoop in files) {
String mediaUrl = await uploadVideo(fileLoop);
mediaUrlS.add(mediaUrl);
}
createPostInFirestore(
mediaUrl: mediaUrlS,
description: captionController.text,
);
captionController.clear();
setState(() {
files = [];
isUploading = false;
postId = Uuid().v4();
selected = false;
});
}
Scaffold buildUploadForm() {
return Scaffold(
appBar: AppBar(
title: Text(
"Tu video",
style: TextStyle(color: Colors.black),
),
actions: [
FlatButton(
onPressed: files.length < 2 ? selectImage(context) : null,
child: Text(
'Seleccionar otro video',
),
),
FlatButton(
onPressed: isUploading ? null : () => handleSubmit(),
child: Text(
"Mandar",
),
),
],
),
body: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: files.length,
itemBuilder: (BuildContext context, int index) {
final File fileBuilder = files[index];
return Container(
height: 220.0,
width: MediaQuery.of(context).size.width * 0.8,
child: Center(
child: AspectRatio(
aspectRatio: 16 / 9,
child: Container(
child: ChewieListItem(
videoUrl: fileBuilder.path,
network: false,
file: fileBuilder,
),
),
),
),
);
}),
);
}
Widget buildNormalScreen () {
return Container(
child: GestureDetector(
onTap: () {
selectImage(context);
},
child: Container(
height: 50.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30.0),
color: Theme.of(context).accentColor,
),
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Subir videos',
style: TextStyle(
fontFamily: 'Comfortaa',
fontSize: 17.0,
color: Colors.white,
),
),
],
),
),
),
),
);
}
#override
Widget build(BuildContext context) {
return !selected
? buildNormalScreen()
: buildUploadForm();
}
}
In the function at the top, I also tried doing something like ImagePicker.pickVideo().then((file){...}) but it didn't work.
I also added <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> to my "android/app/src/main/AndroidManifest.xml" file.
I also tried adding android:requestLegacyExternalStorage="true" inside the <application> tag in my "android/app/src/main/AndroidManifest.xml" file, but then I get an error:
I don't know what I should be changing either in my code or in one of the files in the android folder, any help is deeply appreciated.
Thank you very much in advance
Put the condition in the same function.
handleChooseFromGallery() async {
Navigator.pop(context);
File filePicked = await ImagePicker.pickVideo(
source: ImageSource.gallery,
maxDuration: Duration(seconds: 90),
//This line always returns false
print({'is file not null': filePicked != null});
setState(() {
if (filePicked != null) {
this.files.add(filePicked);
this.selected = true;
} else {
showError();
}
});
}
);