Url Launcher with CUBIT - flutter

I'm new to flutter and bloc cubit.Trying to learn cubit and use url_launcher package in my app. I'm using mealdb's API and go to youtube video with it. I found youtube link inside the API created repository and everything just cant get to launch youtube side. I cant see anything in debug console either. Checked the yaml file to url_launcher package its up to date.
This my screen side:
GestureDetector(
onTap: () {
context.read<FoodDetailsCubit>().urlLauncher; }, child: Container(height: 6.h, width: 65.w,
margin: EdgeInsets.only(right: 2.w),
decoration: youtubeBoxDecoration(),
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [ Icon(Icons.smart_display_outlined, size: 5.5.h,
color: AppColors.white,),
SizedBox(width: 1.w,),
Text("Watch the Tutorial Video",style: Styles.normalWhiteBoldFontStyle(),)
],
),
),
),
),
cubit.dart side:
class FoodDetailsCubit extends Cubit<FoodDetailsState> {
FoodDetailsCubit() : super(FoodDetailsState()) {
loadFoodDetails(52772);
}
final FoodDetailsService api = FoodDetailsService();
Future<void> loadFoodDetails(int foodId) async {
try {
emit(state.copyWith(
foodDetailsStatus: ApiRequest.requestInProgress,
));
final response = (await api.getResFoodDetailsWithId(foodId))?.data;
print(response);
if (response?.meals != null) {
emit(state.copyWith(
foodDetailsStatus: ApiRequest.requestSuccess,
foodDetails: response,
));
} else {
emit(state.copyWith(
foodDetailsStatus: ApiRequest.requestFailure,
));
}
} catch (e) {
emit(state.copyWith(
foodDetailsStatus: ApiRequest.requestFailure,
));
}
}
Future<void> urlLauncher(Uri url) async{
final Uri url = Uri.parse('${state.foodDetails?.meals?[0].strYoutube}');
if (await launchUrl(url)) {
throw 'Could not launch video';
}
}
}
But nothing happens when i press tthe button.

I found the solution:
cubit.dart:
Future<void> urlLauncher(Uri url) async{
final Uri url = Uri.parse('${state.foodDetails?.meals?[0].strYoutube}');
final Uri url2 =
Uri.parse("https://www.youtube.com/watch?v=4aZr5hZXP_s");
if (await launchUrl(url)) {
throw 'Could not launch video';
}
}
view side:
GestureDetector(
onTap: () {
context
.read<FoodDetailsCubit>()
.urlLauncher(Uri());
},
child: Container(
height: 6.h,
width: 65.w,
margin: EdgeInsets.only(right: 2.w),
decoration: youtubeBoxDecoration(),
child: Center(
child: Row(
mainAxisAlignment:
MainAxisAlignment.center,
crossAxisAlignment:
CrossAxisAlignment.center,
children: [
Icon(
Icons.smart_display_outlined,
size: 5.5.h,
color: AppColors.white,
),
SizedBox(
width: 1.w,
),
Text(
"Watch the Tutorial Video",
style: Styles
.normalWhiteBoldFontStyle(),
)
],
),
),
),
),

Related

Display updated value everytime button is press firebase flutter

i am trying to displaying the new value every time the user click the button but it keeps displaying the old data. I need to hot restart to see the new data after i update it. I do not know what i did wrong because i am still learning. This is my full code. I hope someone can help me because i am stuck here 3 hours +
TextEditingController _reloadEditingController = new TextEditingController();
int balance = 0;
late int s = int.parse(_reloadEditingController.text);
final _formKey = GlobalKey<FormState>();
String? name;
String email = '';
String phoneNumber = '';
String imageUrl = '';
String joinedAt = '';
String location = '';
void reload() async {
FirebaseFirestore.instance
.collection("users")
.doc(widget.userID)
.update({"balance": balance + s});
}
void getUserData() async {
try {
_isLoading = true;
final DocumentSnapshot userDoc = await FirebaseFirestore.instance
.collection('users')
.doc(widget.userID)
.get();
if (userDoc == null) {
return;
} else {
setState(() {
name = userDoc.get('name');
email = userDoc.get('email');
phoneNumber = userDoc.get('phoneNumber');
imageUrl = userDoc.get('userImage');
location = userDoc.get('location');
balance = userDoc.get('balance');
});
final FirebaseAuth _auth = FirebaseAuth.instance;
User? user = _auth.currentUser;
final _uid = user!.uid;
setState(() {
_isSameUser = _uid == widget.userID;
});
}
} catch (error) {
} finally {
_isLoading = false;
}
}
void initState() {
super.initState();
getUserData();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.teal[300],
appBar: AppBar(
title: const Text('Wallet'),
flexibleSpace: Container(
color: Colors.teal[300],
),
leading: IconButton(
onPressed: () {
final FirebaseAuth _auth = FirebaseAuth.instance;
final User? user = _auth.currentUser;
final String uid = user!.uid;
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (_) => ProfileScreen(
userID: uid,
)));
},
icon: Icon(Icons.arrow_back, size: 40, color: Colors.white)),
),
body: ListView(
children: [
Column(
children: [
Container(
width: 300,
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
color: Color(0xFF006e6e)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text(
name!,
style: TextStyle(color: Colors.white, fontSize: 18),
),
],
),
],
),
),
Container(
padding: EdgeInsets.all(10),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 25),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
children: [
Text(
"Balance",
),
],
),
Row(
children: [
Text(
'RM',
),
Container(
child: FutureBuilder<DocumentSnapshot>(
future: FirebaseFirestore.instance
.collection('users')
.doc(widget.userID)
.get(),
builder: (context, snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
}
return Text(balance.toString());
},
),
),
],
),
Row(
children: [
Text("Reload your E-Wallet",
)
],
),
Row(
children: [
Form(
key: _formKey,
child: Expanded(
child: TextFormField(
controller: _reloadEditingController,
keyboardType: TextInputType.phone,
),
),
)
],
)
],
),
),
),
Container(
width: 320,
child: MaterialButton(
onPressed: () {
reload();
},
child: Padding(
padding: EdgeInsets.symmetric(vertical: 14),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Reload E-Wallet",
)
],
),
),
),
),
],
)
],
));
You need yo call getUserData when you update your data so change your reload to this:
void reload() async {
int s = int.parse(_reloadEditingController.text); // define this hear
await FirebaseFirestore.instance
.collection("users")
.doc(widget.userID)
.update({"balance": balance + s});
setState(() {});
}
Solution of this problem depends on Stream, because you want the live data.
You want to upload data and download it for show in the UI.
If you try to use StreamBuilder instead of FutureBuilder, I think it may be help..
For me I use GetX package, and since a while I faced the same problem, I will put the URL for my question and see if you can take an idea..
Flutter: live stream with getx has a problem, it shows data without updating

How to implement objectbox into flutter appilcation

I am working on an app, and need help trying to change my save method to object box. I have been using path_provider to save data but want to switch it to the object box database but I am struggling to do it. The goal is to have each timer button be clicked to record a time and present them back to the user to see how long each task/button took. Below is my code for my ViewModel and my timer_page dart files.
#Entity()
class StudyViewModel {
static List<Study> studies = [];
static List<ValueChanged<ElapsedTime>> timerListeners =
<ValueChanged<ElapsedTime>>[];
static Stopwatch stopwatch = new Stopwatch();
/// load from file...
static Future load() async {
try {
File file = await getFile();
String studiesJson = await file.readAsString();
if (studiesJson.isNotEmpty) {
List studiesParsed = json.decode(studiesJson);
studies = studiesParsed.map((i) => Study.fromJson(i)).toList();
}
} catch (e) {
print(e);
}
}
static Future<File> getFile() async {
final directory = await getApplicationDocumentsDirectory();
final path = directory.path;
return File('$path/studies.json');
}
static Future saveFile() async {
File file = await getFile();
file.writeAsString(json.encode(studies));
}
SizedBox(
height: 600,
child: GridView.count(
primary: false,
padding: const EdgeInsets.all(20),
crossAxisSpacing: 10,
mainAxisSpacing: 10,
crossAxisCount: 3,
children: widget.tasks.map((element) {
final isActive = activeTask != null && activeTask == element;
return GestureDetector(
onTap: () {
// set active task or toggle is active
if (isActive) {
setState(() {
activeTask = null;
StudyViewModel.stopwatch.start();
disable = true;
});
} else {
setState(() {
activeTask = element;
StudyViewModel.stopwatch.stop();
disable = false;
});
}
},
child: Container(
color: isActive ? Colors.amber : Colors.green,
padding: EdgeInsets.all(8),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
element.name,
style: TextStyle(color: Colors.white, fontSize: 25),
textAlign: TextAlign.center,
),
Text(
element.elapsedTime
)
]
),
),
);
}).toList(),
),
),
Expanded(
child: timerText,
),
Expanded(
flex: 0,
child: Padding(
padding: const EdgeInsets.only(bottom: 24.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
RaisedButton(
onPressed: disable
? null
: () {
setState(() {
StudyViewModel.stopwatch.reset();
});
},
color: Colors.red,
padding: EdgeInsets.symmetric(
horizontal: 60.0,
vertical: 20.0,
),
child: Text(
"Reset",
style: TextStyle(fontSize: 20.0, color: Colors.white),
),
),
RaisedButton(
onPressed: disable
? null
: () async {
await showDialog(
context: context,
builder: (context) {
return AlertDialog(
content: Text('Do you wish to save a time study?'),
actions: <Widget>[
FlatButton(
child: Text('Accept'),
onPressed: () async {
StudyViewModel.saveFile();
Navigator.of(context).pop();
},
),
FlatButton(
child: Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
]
);
}
);

How to share text with image on flutter excluding icons?

I am currently able to share the text on top of the image using share package but I want to share the image and text along with it without my icons of refresh and share. Couldn't find any answers for this. Have used multiple share packages but couldn't achieve the expected result.
Widget build(BuildContext context) {
return Scaffold(
body: Stack(children: <Widget>[
Container(
constraints: BoxConstraints.expand(),
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage("${imgUrl}$count"),
fit: BoxFit.fill)
),
),
FutureBuilder<Advice>(
future: advice,
builder: (context, snapshot) {
if (snapshot.hasData) {
return SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
margin: EdgeInsets.only(left: 30.0),
child: FadeTransition(
opacity: _animation,
child: Text(
snapshot.data!.adviceText,
style: TextStyle(
decoration: TextDecoration.none,
fontSize: 30.0,
color: Colors.white,
fontFamily: 'quoteScript'),
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
IconButton(
icon: Icon(Icons.refresh, color: Colors.white),
onPressed: () async {
setState(() {
_controller.reset();
_controller.forward();
count++;
advice = fetchAdvice();
});
},
),
IconButton(
icon: Icon(Icons.share, color: Colors.white),
onPressed: () {
Share.share("Here's an advice for you: ${snapshot.data!.adviceText}");
},
),
],
),
],
),
);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
// By default, show a loading spinner.
return Center(child: CircularProgressIndicator());
},
),
]),
);
}
This is the text and image widget. Can be shared with the dynamic text.
SHARE: The best way I think is to use screenshot package to capture the widget which contains both image and text that you need to share, then share it as a picture with share_plus package.
For instance:
// Create a controller
ScreenshotController screenshotController = ScreenshotController();
[...]
// Wrap the widget which you want to capture with `Screenshot`
Screenshot<Widget>(
controller: screenshotController,
child: Container(
child: [...]
),
),
[...]
// Create a method to take a screenshot and share it
// This method I get from my project, so you can modify it to fit your purpose
Future<void> shareScreen(String title, String name) async {
final screenShot = await screenshotController.capture();
if (screenShot != null) {
final Directory tempDir = await getTemporaryDirectory();
final File file = await File('${tempDir.path}/$name').create();
await file.writeAsBytes(screenShot);
await Share.shareFiles(<String>[file.path], subject: title, text: name);
file.delete();
}
}
Then replace the Share.share method in the below example with the shareScreen method just created above.
HIDE BUTTON: You can create a new variable like bool isSharing = false; to control the visible state of those 2 buttons. The important part is the Share.share method must be an async method to make the code works because it needs await to know when the share action is done.
For instance:
[...]
if (!isSharing) // <--- Add this line
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
IconButton(
icon: Icon(Icons.refresh, color: Colors.white),
onPressed: () async {
setState(() {
_controller.reset();
_controller.forward();
count++;
advice = fetchAdvice();
});
},
),
IconButton(
icon: Icon(Icons.share, color: Colors.white),
// And modify here <---
onPressed: () async {
setState(() => isSharing = true); // Hide the buttons
await Share.share(
"Here's an advice for you: ${snapshot.data!.adviceText}");
setState(() => isSharing = false); // Show the buttons
},
),
],
),
[...]

Flutter - Image.memory not refreshing after source change

I have a page that allows users to upload documents (as images). I have structured my page in a way that for each document type that can be uploaded a Document_Upload widget is used to reduce the amount of repeated code.
On initial load I use a FutureBuilder to get all the documents the user has already uploaded from our REST Api and then populate each Document_Upload widget with the relevant data.
On successful upload our REST Api returns the new image back to the Flutter app as a Byte Array so it can be displayed.
The problem I am currently facing is that no matter what I try the image widget (Image.memory) does not display the new image, it just stays on the old one.
I have tried almost everything I can think of/ find online to resolve this issue, including:
Calling setState({}); after updating the imageString variable - I can see the widget flash but it remains on the original image.
Using a function to callback to the parent widget to rebuild the entire child widget tree - same result as setState, all the widgets flash, but no update.
Calling imageCache.clear() & imageCache.clearLiveImages() before updating the imageString.
Using CircleAvatar instead of Image.memory.
Rebuilding the Image widget by calling new Image.memory() inside the setState call.
I am starting to question if this is an issue related to Image.memory itself, however, using Image.File / Image.network is not an option with our current requirement.
Refreshing the page manually causes the new image to show up.
My code is as follows:
documents_page.dart
class DocumentsPage extends StatefulWidget {
#override
_DocumentsPageState createState() => _DocumentsPageState();
}
class _DocumentsPageState extends State<DocumentsPage>
with SingleTickerProviderStateMixin {
Future<Personal> _getUserDocuments;
Personal _documents;
#override
void didChangeDependencies() {
super.didChangeDependencies();
_getUserDocuments = sl<AccountProvider>().getUserDocuments();
}
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: SafeArea(
child: Center(
child: Padding(
padding: EdgeInsets.all(20),
child: Container(
constraints: BoxConstraints(maxWidth: 1300),
child: buildFutureBuilder(context)),
)),
),
);
}
Widget buildFutureBuilder(BuildContext context) {
var screenSize = MediaQuery.of(context).size;
return FutureBuilder<Personal>(
future: _getUserDocuments,
builder: (context, AsyncSnapshot<Personal> snapshot) {
if (!snapshot.hasData) {
return Text("Loading");
} else {
if (snapshot.data == null) {
return Center(child: Text('Error: ${snapshot.error}'));
} else {
_documents = snapshot.data;
return Column(
children: [
SizedBox(height: 20.0),
Text(
"DOCUMENTS",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
color: AppColors.navy),
),
Container(
constraints: BoxConstraints(maxWidth: 250),
child: Divider(
color: AppColors.darkBlue,
height: 20,
),
),
Container(
margin: EdgeInsets.only(top: 5.0, bottom: 5.0),
child: Text(
"These documents are required in order to verify you as a user",
style: TextStyle(fontSize: 14))),
Container(
margin: EdgeInsets.only(bottom: 25.0),
child: Text("View our Privacy Policy",
style: TextStyle(fontSize: 14))),
Container(
child: screenSize.width < 768
? Column(
children: [
DocumentUpload(
imageType: "ID",
imageString: _documents.id),
DocumentUpload(
imageType: "Drivers License Front",
imageString: _documents.driversLicenseFront,
),
DocumentUpload(
imageType: "Drivers License Back",
imageString: _documents.driversLicenseBack,
)
],
)
: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
DocumentUpload(
imageType: "ID",
imageString: _documents.id),
DocumentUpload(
imageType: "Drivers License Front",
imageString: _documents.driversLicenseFront,
),
DocumentUpload(
imageType: "Drivers License Back",
imageString: _documents.driversLicenseBack,
),
])),
Container(
child: screenSize.width < 768
? Container()
: Padding(
padding:
EdgeInsets.only(top: 10.0, bottom: 10.0))),
Container(
child: screenSize.width < 768
? Column(
children: [
DocumentUpload(
imageType: "Selfie",
imageString: _documents.selfie,
),
DocumentUpload(
imageType: "Proof of Residence",
imageString: _documents.proofOfResidence,
),
Container(width: 325)
],
)
: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
DocumentUpload(
imageType: "Selfie",
imageString: _documents.selfie,
),
DocumentUpload(
imageType: "Proof of Residence",
imageString: _documents.proofOfResidence,
),
Container(width: 325)
])),
],
);
}
}
});
}
}
document_upload.dart
class DocumentUpload extends StatefulWidget {
final String imageType;
final String imageString;
const DocumentUpload({this.imageType, this.imageString});
#override
_DocumentUploadState createState() => _DocumentUploadState();
}
class _DocumentUploadState extends State<DocumentUpload> {
String _imageType;
String _imageString;
bool uploadPressed = false;
Image _imageWidget;
#override
Widget build(BuildContext context) {
setState(() {
_imageType = widget.imageType;
_imageString = widget.imageString;
_imageWidget =
new Image.memory(base64Decode(_imageString), fit: BoxFit.fill);
});
return Container(
constraints: BoxConstraints(maxWidth: 325),
height: 200,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
boxShadow: [
new BoxShadow(
color: AppColors.lightGrey,
blurRadius: 5.0,
offset: Offset(0.0, 3.0),
),
],
),
child: Card(
color: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
child: Column(children: <Widget>[
Padding(padding: EdgeInsets.only(top: 5.0)),
Row(
//ROW 1
children: <Widget>[
Expanded(
child: Text(
_imageType,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: AppColors.darkBlue),
),
),
],
),
Row(
//ROW 2
children: <Widget>[
Expanded(
child: Container(
padding: EdgeInsets.only(left: 5.0, bottom: 5.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(20.0),
child: _imageWidget,
)),
),
Consumer<AccountProvider>(
builder: (context, provider, child) {
return Padding(
padding: EdgeInsets.all(10.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Padding(
padding:
EdgeInsets.only(top: 5.0, bottom: 5.0),
child: Icon(Icons.star,
size: 20, color: AppColors.darkBlue)),
Padding(
padding:
EdgeInsets.only(top: 5.0, bottom: 5.0),
child: Text('Drag file here or',
textAlign: TextAlign.center)),
Padding(
padding:
EdgeInsets.only(top: 5.0, bottom: 5.0),
child: DynamicGreyButton(
title: uploadPressed
? "Uploading ..."
: "Browse",
onPressed: () async {
FilePickerResult result =
await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: [
'jpg',
'jpeg',
'png'
]);
if (result != null) {
uploadPressed = true;
Uint8List file =
result.files.single.bytes;
String fileType =
result.files.single.extension;
await provider
.doUploadDocument(
_imageType, file, fileType)
.then((uploadResult) {
if (uploadResult == null ||
uploadResult == '') {
showToast(
"Document failed to upload");
return;
} else {
showToast("Document uploaded",
Colors.green, "#66BB6A");
uploadPressed = false;
_imageString = uploadResult;
setState(() {});
}
});
} else {
// User canceled the picker
uploadPressed = false;
}
},
))
]));
})
],
),
])));
}
}
Image Upload HTTP Call
#override
Future uploadDocuments(DocumentsUpload model) async {
final response = await client.post(
Uri.https(appConfig.baseUrl, "/api/Account/PostDocuments_Flutter"),
body: jsonEncode(model.toJson()),
headers: <String, String>{
'Content-Type': 'application/json'
});
if (response.statusCode == 200) {
var data = json.decode(response.body);
return data;
} else {
return "";
}
}
EDIT: Attached GIF of current behaviour.
I am pretty much out of ideas at this point, any help would be greatly appreciated.
Came up with a solution.
I created a second variable to hold the new image string and showed an entirely new image widget once the second variable had value.
String _newImage;
In the success of the upload...
_newImage = uploadResult;
setState(() {});
Image widget...
child: (_newImage == null || _newImage == '')
? new Image.memory(base64Decode(_imageString), fit: BoxFit.fill)
: new Image.memory(base64Decode(_newImage), fit: BoxFit.fill)
Not a very elegant solution, but it's a solution, but also not necessarily the answer as to why the original issue was there.

How can I navigate to another page after CircularProgressIndicator completed in Flutter?

Hello I am new in Flutter and I am currently building a chat application.
I got a profile maker screen where the user can upload an image to set their avatar. I am using CircularProgressIndicator() to show an uploading screen. I want to know that how can I navigate to the next screen i.e my main homescreen automatically after uploading completed so that the user doesn't have to wait for any button to press.
Here is the code which I tried
progressString != '100% Completed' ? Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CircularProgressIndicator(
backgroundColor: Colors.blue,
),
SizedBox(
height: 20.0,
),
Text("Uploading File : $progressString",
style: TextStyle(
color: Colors.white54,
fontSize: 20.0,
fontWeight: FontWeight.w900,
),
),
],
) : Navigator.pushReplacement(context,
MaterialPageRoute(builder: (context) {
return LoginPage();
}),
),
Upload Code
FormData data = FormData.fromMap({
"username": userName.toString(),
"name": naMe.toString(),
"birthday": birthDay.toString(),
"about": aboutUser.toString(),
"sender": sendUser.toString(),
"mobile": userMobile.toString(),
"avatar": _image != null
? await MultipartFile.fromFile(_image.path,
filename: avatarName.toString())
: Text('Invalid Avatar'),
});
if (_validateAndSave()) {
final token = widget.token;
try {
Dio dio = Dio();
dio.options.headers['Accept'] = "application/json";
dio.options.headers['Authorization'] = "Bearer $token";
dio.options.headers['Content-Type'] = "multipart/form-data";
dio.options.followRedirects = false;
var response = await dio.post(url,
data: data, onSendProgress: (int rec, int total) {
setState(() {
uploading = true;
progressString = ((rec / total * 100).toString());
});
});
var responseCode = response.statusCode;
print('Dio responseCode : $responseCode');
} on DioError catch (err) {
var responseCode = err.response.statusCode;
print(responseCode);
}
setState(() {
uploading = false;
progressString = "100% Completed ";
print(progressString);
});
}
you should set your navigator inside of your upload function after upload finished
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CircularProgressIndicator(
backgroundColor: Colors.blue,
),
SizedBox(
height: 20.0,
),
Text("Uploading File : $progressString",
style: TextStyle(
color: Colors.white54,
fontSize: 20.0,
fontWeight: FontWeight.w900,
),
),
],
),
 
FormData data = FormData.fromMap({
"username": userName.toString(),
"name": naMe.toString(),
"birthday": birthDay.toString(),
"about": aboutUser.toString(),
"sender": sendUser.toString(),
"mobile": userMobile.toString(),
"avatar": _image != null
? await MultipartFile.fromFile(_image.path,
filename: avatarName.toString())
: Text('Invalid Avatar'),
});
if (_validateAndSave()) {
final token = widget.token;
try {
Dio dio = Dio();
dio.options.headers['Accept'] = "application/json";
dio.options.headers['Authorization'] = "Bearer $token";
dio.options.headers['Content-Type'] = "multipart/form-data";
dio.options.followRedirects = false;
var response = await dio.post(url,
data: data, onSendProgress: (int rec, int total) {
setState(() {
uploading = true;
progressString = ((rec / total * 100).toString());
});
});
var responseCode = response.statusCode;
print('Dio responseCode : $responseCode');
} on DioError catch (err) {
var responseCode = err.response.statusCode;
print(responseCode);
}
Future.delaye(Duration(milliseconds: 100), (){
Navigator.pushReplacement(this.context,
MaterialPageRoute(builder: (context) {
return LoginPage();
}),
);
});
}
When the upload is complete, update the UI to show the user that the upload is complete and add a post frame callback to navigate to the next page.
Step 1 : Create a new file i.e, splashscreen.dart file under lib folder. In main.dart file give reference to SplashScreen().
Filename: main.dart
import 'package:flutter/material.dart';
import 'package:mfitz/splashscreen.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: SplashScreen(),
);
}
}
Step 2: Under splashscreen.dart file create the required UI for the splash screen and include the following code under void initState() method to navigate to the new screen after 5 seconds.
Timer(Duration(seconds: 5), () {
Navigator.of(context)
.pushReplacement(MaterialPageRoute(builder: (_) => MainScreen()));
Splash Screen Code
Filename: splashscreen.dart
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'mainScreen.dart';
class SplashScreen extends StatefulWidget {
#override
_SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
#override
void initState() {
super.initState();
//Navigates to new screen after 5 seconds.
Timer(Duration(seconds: 5), () {
Navigator.of(context)
.pushReplacement(MaterialPageRoute(builder: (_) => MainScreen()));
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
fit: StackFit.expand,
children: [
Container(
constraints: BoxConstraints.expand(),
decoration: BoxDecoration(
image: new DecorationImage(
image: AssetImage('assets/images/img2.jpg'),
fit: BoxFit.fill,
),
),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
flex: 2,
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircleAvatar(
backgroundColor: Colors.grey[100],
radius: 80.0,
child: Text(
"MOBIFIT.",
style: GoogleFonts.aldrich(
fontWeight: FontWeight.bold,
color: Colors.black,
fontSize: 30.0),
textAlign: TextAlign.center,
),
),
],
),
),
),
Expanded(
flex: 1,
child: Column(
children: [
Padding(
padding: EdgeInsets.only(right: 100.0, left: 100.0),
child: LinearProgressIndicator(
backgroundColor: Colors.white,
valueColor:
AlwaysStoppedAnimation<Color>(Colors.grey),
minHeight: 10.0,
),
),
Padding(padding: EdgeInsets.only(bottom: 10.0))
],
))
],
)
],
),
);
}
}
SPLASHSCREEN
MAINSCREEN