Flutter - CircularProgressIndicator won't stop executing - flutter

My problem is that the CircularProgressIndicator won't stop buffering. My goal is when the video detects a lagging status then the CircularProgressIndicator will show and when it plays again then the CircularProgressIndicator will stop showing.
bool vidBuffering = true;
void buffer() {
setState(() {
vidBuffering = !vidBuffering;
});
}
This is inside a widget where I call the vidBuffering
Widget _buildPlayStack() {
return Stack(
children: [
_buildPlay(),
child: FlatButton(
onPressed: () => setState(() {
_vidController.value.isPlaying ? _vidController.pause() :_vidController.play();
}),
child: Center(
child: (_vidController.value.isPlaying)
? Icon(Icons.pause, color: Colors.green)
: Icon(Icons.play_arrow, color: Colors.green),
),
),
Center(
child: _vidBuffering
? const CircularProgressIndicator()
: null),
],
);
}
Widget _buildPlay() {
return Container(
child: AspectRatio(
aspectRatio: _vidController.value.aspectRatio,
child: VideoPlayer(_controller),
),
);
}

You should be used StreamBuilder for update only Loader
For Example :
class Demo extends StatefulWidget {
#override
_DemoState createState() => _DemoState();
}
class _DemoState extends State<Demo> {
bool vidBuffering = true;
StreamController streamControllerBuffering = StreamController();
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
_buildPlayStack(),
RaisedButton(
onPressed: () => buffer(),
child: Text(vidBuffering ? 'Hide' : 'Show'),
)
],
),
),
);
}
void buffer() {
vidBuffering = !vidBuffering;
streamControllerBuffering.sink.add(vidBuffering);
}
Widget _buildPlayStack() {
return Stack(
children: [
_buildPlay(),
FlatButton(
onPressed: () => setState(() {
/*_vidController.value.isPlaying
? _vidController.pause()
: _vidController.play();*/
}),
child: Center(
child: (/*_vidController.value.isPlaying*/ true)
? Icon(Icons.pause, color: Colors.green)
: Icon(Icons.play_arrow, color: Colors.green),
),
),
Center(
child: StreamBuilder(
initialData: true,
stream: streamControllerBuffering.stream,
builder: (builder, snapshot) {
if (snapshot.hasData && snapshot.data) {
return CircularProgressIndicator();
} else {
Offstage();
}
return Offstage();
}),
),
],
);
}
Widget _buildPlay() {
return Container(
height: 200,
width: 200,
color: Colors.amber,
);
}
#override
void dispose() {
streamControllerBuffering.close();
super.dispose();
}
}

Related

Flutter not showing CircularProgressIndicator

I'm developing simple webview applicatoin using flutter , here i used CircularProgressIndicator but its not showing.
Package i use: https://pub.dev/packages/flutter_webview_plugin
How i can show the loading using CircularProgressIndicator in flutter ?, I'm using stack to show the loading indicator the centor of it.
class _MyHomePageState extends State<MyHomePage> {
final flutterWebViewPlugin = FlutterWebviewPlugin();
bool isLoading = true;
double webProgress = 0;
#override
void initState() {
super.initState();
flutterWebViewPlugin.onProgressChanged.listen((double progress) {
setState(() {
this.webProgress = progress;
});
print("The progress is $progress");
});
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: WillPopScope(
onWillPop: () async {
print("back pressed");
return false;
},
child: Stack(
children: [
Column(
children: [
webProgress < 1
? SizedBox(
height: 5,
child: LinearProgressIndicator(
value: webProgress,
color: Colors.blue,
backgroundColor: Colors.white,
),
)
: SizedBox(),
Expanded(
child: WebviewScaffold(
url: "https://google.com",
mediaPlaybackRequiresUserGesture: false,
withLocalStorage: true,
),
),
],
),
isLoading
? Center(
child: CircularProgressIndicator(
color: Colors.red,
),
)
: Stack(),
],
),
),
));
}
}

splash screen before webview loads in flutter

I am trying to build an app that uses webview but before loading it I need an splashscreen that checks if there is internet connection and if there isn't it shows an Snackbar in splashscreen. Do you know how to achieve this?
Use this plugin
https://pub.dev/packages/connectivity_plus
Future<bool> checkInternet() async {
var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.mobile) {
return true;
} else if (connectivityResult == ConnectivityResult.wifi) {
return true;
}
return false;
}
Use it like this
if (!(await checkInternet())) {
///show your snackBar here
}
This would help. I achieved this in my personal project.
As you can see am using internet_connection_checker and whenever the internet is down I do a retry which was achieved by calling a restart widget in the main method to safely perform a restart whenever the internet is restored
Splash Page
import 'dart:async';
import 'package:airduka/main.dart';
import 'package:airduka/models/user_model.dart';
import 'package:airduka/widgets/color.dart';
import 'package:airduka/widgets/custom_navigations.dart';
import 'package:airduka/widgets/small_text.dart';
import 'package:flutter/material.dart';
import 'package:internet_connection_checker/internet_connection_checker.dart';
import 'package:page_transition/page_transition.dart';
class SplashPage extends StatefulWidget {
final String title, description, time;
final UserModel? user;
final List<dynamic>? listMsg;
const SplashPage({Key? key, this.listMsg, required this.title, required this.description, required this.time, this.user}) : super(key: key);
#override
_SplashPageState createState() => _SplashPageState();
}
class _SplashPageState extends State<SplashPage> {
Timer? timer;
Future<InternetConnectionStatus> dataConnection() async{
InternetConnectionStatus statusMain = InternetConnectionStatus.disconnected;
final StreamSubscription<InternetConnectionStatus> listener =
InternetConnectionChecker().onStatusChange.listen(
(InternetConnectionStatus status) {
switch (status) {
case InternetConnectionStatus.connected:
statusMain = InternetConnectionStatus.connected;
break;
case InternetConnectionStatus.disconnected:
statusMain = InternetConnectionStatus.disconnected;
break;
}
},
);
// close listener after 30 seconds, so the program doesn't run forever
await Future<void>.delayed(const Duration(seconds: 1));
await listener.cancel();
return statusMain;
}
#override
void initState() {
timer = Timer(
const Duration(seconds: 5),() => Navigator.pushReplacement(
context,
PageTransition(
child: FutureBuilder<InternetConnectionStatus>(
future: dataConnection(),
builder: (context, AsyncSnapshot snapshot) {
switch(snapshot.connectionState){
case ConnectionState.none:
case ConnectionState.waiting:
return Scaffold(
extendBodyBehindAppBar: true,
backgroundColor: const Color(0xFF00639E),
body: Center(
child: Image.asset(
"assets/animations/jety.gif",
height: 200,
),
),
);
default:
if(snapshot.hasError)
return Scaffold(
extendBodyBehindAppBar: true,
backgroundColor: const Color(0xFF00639E),
body: Center(
child: Image.asset(
"assets/animations/jety.gif",
height: 200,
),
),
);
else if(snapshot.data == InternetConnectionStatus.disconnected)
return Scaffold(
extendBodyBehindAppBar: true,
backgroundColor: const Color(0xFF00639E),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Center(
child: Image.asset(
"assets/animations/jety.gif",
height: 200,
),
),
const SmallTextWidget(text: "You seem to be offline", color: AppColors.whiteThemeColor,),
const SizedBox(height: 8.0,),
InkWell(
onTap: (){
RestartWidget.restartApp(context);
},
child: Container(
height: 45,
width: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5.0),
color: AppColors.whiteThemeColor
),
child: const Center(child: Text("Retry", style: TextStyle(color: AppColors.blackThemeColor, fontSize: 14.0, fontWeight: FontWeight.bold),)),
),
),
],
),
);
else Scaffold(
extendBodyBehindAppBar: true,
backgroundColor: const Color(0xFF00639E),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Center(
child: Image.asset(
"assets/animations/jety.gif",
height: 200,
),
),
const SmallTextWidget(text: "Something wrong happened!", color: AppColors.whiteThemeColor,),
const SizedBox(height: 8.0,),
InkWell(
onTap: (){
RestartWidget.restartApp(context); //call restart here
},
child: Container(
height: 45,
width: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5.0),
color: AppColors.whiteThemeColor
),
child: const Center(child: Text("Retry", style: TextStyle(color: AppColors.blackThemeColor, fontSize: 14.0, fontWeight: FontWeight.bold),)),
),
),
],
),
);
return CustomNavigation(msgList: widget.listMsg, user: widget.user,);
}
}),
type: PageTransitionType.fade))
);
super.initState();
}
#override
void dispose() {
timer?.cancel();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
extendBodyBehindAppBar: true,
backgroundColor: const Color(0xFF00639E),
body: Center(
child: Image.asset(
"assets/animations/jety.gif",
height: 200,
),
),
);
}
}
Restart Widget in the main method
class RestartWidget extends StatefulWidget {
const RestartWidget({required this.child});
final Widget child;
static void restartApp(BuildContext context) {
context.findAncestorStateOfType<_RestartWidgetState>()!.restartApp();
}
#override
_RestartWidgetState createState() => _RestartWidgetState();
}
class _RestartWidgetState extends State<RestartWidget> {
Key key = UniqueKey();
void restartApp() {
setState(() {
key = UniqueKey();
});
}
#override
Widget build(BuildContext context) {
return KeyedSubtree(
key: key,
child: widget.child,
);
}
}
You can use internet_connection_checker for internet check
bool result = await InternetConnectionChecker().hasConnection;
if(result == true) {
print('YAY! Free cute dog pics!');
} else {
print('No internet :( Reason:');
}
call this code in init method in SplashScreen

How to play multiple videos with (player_video) package

I have created this video player for my application which can play video from assets. Since, It is made from (video_player) package I guess I can play only one video with it But I want 3-4 videos to be played. How can I do that? It is possible or not...Help me! Furthermore, I also want to make the video the option of 10 seconds backward and forward while pressing it's sides. Thanks for your help!
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
void main() {
runApp(VideoPlay());
}
class VideoPlay extends StatefulWidget {
String? pathh;
#override
_VideoPlayState createState() => _VideoPlayState();
VideoPlay({
this.pathh = "assets/video.mp4", // Video from assets folder
});
}
class _VideoPlayState extends State<VideoPlay> {
late VideoPlayerController controller;
late Future<void> futureController;
#override
void initState() {
//url to load network
controller = VideoPlayerController.asset(widget.pathh!);
futureController = controller.initialize();
controller.setLooping(true);
controller.setVolume(25.0);
super.initState();
}
#override
void dispose() {
controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
Center(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: FutureBuilder(
future: futureController,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: VideoPlayer(controller));
} else {
return Center(
child: CircularProgressIndicator(),
);
}
},
),
),
),
Padding(
padding: const EdgeInsets.all(6.0),
child: RaisedButton(
color: Color(0xff9142db),
child: Icon(
controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
color: Colors.white,
),
onPressed: () {
setState(() {
if (controller.value.isPlaying) {
controller.pause();
} else {
controller.play();
}
});
},
),
)
],
));
}
}
App Image Is Here
I like your idea and wanted to deal with it, this is the result.
I hope you can do better.
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
void main(List<String> args) {
runApp(Example());
}
class Example extends StatelessWidget {
const Example({
Key? key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return const MaterialApp(
color: Colors.white,
debugShowCheckedModeBanner: false,
home: VideoPlayersList(),
);
}
}
class VideoPlayersList extends StatelessWidget {
const VideoPlayersList({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
List<String> paths = [
"assets/images/testvideo.mp4",
"assets/images/testvideo.mp4",
"assets/images/testvideo.mp4",
"assets/images/testvideo.mp4",
"assets/images/testvideo.mp4",
];
return Scaffold(
body: SingleChildScrollView(
child: Column(children: [
ListView.builder(
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
itemCount: paths.length,
itemBuilder: (BuildContext context, int index) {
return VideoPlay(
pathh: paths[index],
);
},
),
]),
),
);
}
}
class VideoPlay extends StatefulWidget {
String? pathh;
#override
_VideoPlayState createState() => _VideoPlayState();
VideoPlay({
Key? key,
this.pathh, // Video from assets folder
}) : super(key: key);
}
class _VideoPlayState extends State<VideoPlay> {
ValueNotifier<VideoPlayerValue?> currentPosition = ValueNotifier(null);
VideoPlayerController? controller;
late Future<void> futureController;
initVideo() {
controller = VideoPlayerController.asset(widget.pathh!);
futureController = controller!.initialize();
}
#override
void initState() {
initVideo();
controller!.addListener(() {
if (controller!.value.isInitialized) {
currentPosition.value = controller!.value;
}
});
super.initState();
}
#override
void dispose() {
controller!.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: futureController,
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator.adaptive();
} else {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
child: SizedBox(
height: controller!.value.size.height,
width: double.infinity,
child: AspectRatio(
aspectRatio: controller!.value.aspectRatio,
child: Stack(children: [
Positioned.fill(
child: Container(
foregroundDecoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.black.withOpacity(.7),
Colors.transparent
],
stops: [
0,
.3
],
begin: Alignment.bottomCenter,
end: Alignment.topCenter),
),
child: VideoPlayer(controller!))),
Positioned.fill(
child: Column(
children: [
Expanded(
flex: 8,
child: Row(
children: [
Expanded(
flex: 3,
child: GestureDetector(
onDoubleTap: () async {
Duration? position =
await controller!.position;
setState(() {
controller!.seekTo(Duration(
seconds: position!.inSeconds - 10));
});
},
child: const Icon(
Icons.fast_rewind_rounded,
color: Colors.black,
size: 40,
),
),
),
Expanded(
flex: 4,
child: IconButton(
icon: Icon(
controller!.value.isPlaying
? Icons.pause
: Icons.play_arrow,
color: Colors.black,
size: 40,
),
onPressed: () {
setState(() {
if (controller!.value.isPlaying) {
controller!.pause();
} else {
controller!.play();
}
});
},
)),
Expanded(
flex: 3,
child: GestureDetector(
onDoubleTap: () async {
Duration? position =
await controller!.position;
setState(() {
controller!.seekTo(Duration(
seconds: position!.inSeconds + 10));
});
},
child: const Icon(
Icons.fast_forward_rounded,
color: Colors.black,
size: 40,
),
),
),
],
),
),
Expanded(
flex: 2,
child: Align(
alignment: Alignment.bottomCenter,
child: ValueListenableBuilder(
valueListenable: currentPosition,
builder: (context,
VideoPlayerValue? videoPlayerValue, w) {
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20, vertical: 10),
child: Row(
children: [
Text(
videoPlayerValue!.position
.toString()
.substring(
videoPlayerValue.position
.toString()
.indexOf(':') +
1,
videoPlayerValue.position
.toString()
.indexOf('.')),
style: const TextStyle(
color: Colors.white,
fontSize: 22),
),
const Spacer(),
Text(
videoPlayerValue.duration
.toString()
.substring(
videoPlayerValue.duration
.toString()
.indexOf(':') +
1,
videoPlayerValue.duration
.toString()
.indexOf('.')),
style: const TextStyle(
color: Colors.white,
fontSize: 22),
),
],
),
);
}),
))
],
),
),
])),
),
);
}
},
);
}
}

Can I change the widget using if?

For example
if TEXT = "text1'
than page = mainpage(),
else if TEXT = "text2'
than page = mainpage2(),
and
after if the TEXT is other source code string various
how can I cording
:<
plz help me
additional
class Categorylist extends StatefulWidget {
#override
_CategorylistState createState() => _CategorylistState();
}
class _CategorylistState extends State<Categorylist> {
int selectedCategory = 0;
List<String> categories = ["통합정보", "지역 구인글", "나를 위한 구인글", "같은 국가 추천업", "같은 국가 커뮤니티"];
#override
Widget build(BuildContext context) {
return Container(
alignment: Alignment.bottomCenter,
margin: EdgeInsets.symmetric(vertical: kDefaultPadding / 2),
height: 61,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: categories.length,
itemBuilder: (context, index) => buildCategory(index, context),
),
);
}
Padding buildCategory(int index, BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: kDefaultPadding),
child: GestureDetector(
onTap: () {
setState(() {
selectedCategory = index;
});
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
categories[index],
style: Theme.of(context).textTheme.bodyText1.copyWith(
fontWeight: FontWeight.w500,
color: index == selectedCategory
? kTextColor
: Colors.black.withOpacity(0.4),
),
),
Container(
margin: EdgeInsets.symmetric(vertical: kDefaultPadding / 2),
alignment: Alignment.center,
height: 6,
width: 40,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: index == selectedCategory
? kSecondaryColor
: Colors.transparent,
),
)
],
),
),
);
}
}
class ChangePage extends StatelessWidget {
const ChangePage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: ChangeBody(),
);
}
}
class ChangeBody extends StatelessWidget {
const ChangeBody({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
if (categories == '통합정보') [
ChangeBody() = mainpage()
]
else (categories == '지역 구인글')[
ChangeBody() = RegionJob()
],
],
),;
}
}
this is my code to edit by your advice ,
but I need more help to where insert my if code
and my if code is categories ,ChangeBody() = mainpage() is got redline,
Container(
padding: EdgeInsets.all(8.0),
height: 100,
child: Row(
children: [
true
? Text("No button")
: ElevatedButton(onPressed: () {}, child: Text("button"))
],
),
)
OR
Container(
padding: EdgeInsets.all(8.0),
height: 100,
child: Row(
children: [
if (true)
Text("No button")
else
ElevatedButton(onPressed: () {}, child: Text("button")),
],
),
)
OR
Outside the build method declare mywidget method
Container(
padding: EdgeInsets.all(8.0),
height: 100,
child: Row(
children: [
mywidget(),
],
),
)
mywidget() {
if (true)
return Text("No button");
else
return ElevatedButton(onPressed: () {}, child: Text("button"));
}
OR
Outside the build method declare button variable
var button = true
? Text("No button")
: ElevatedButton(onPressed: () {}, child: Text("button"));
Row(
children: [
mywidget(),
button,
true
? Text("No button")
: ElevatedButton(onPressed: () {}, child: Text("button")),
if (true)
Text("No button")
else
ElevatedButton(onPressed: () {}, child: Text("button")),
],
)
FullCode
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(MaterialApp(home: Mainwidget()));
}
class Mainwidget extends StatefulWidget {
const Mainwidget({Key? key}) : super(key: key);
#override
_MainwidgetState createState() => _MainwidgetState();
}
class _MainwidgetState extends State<Mainwidget> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Container(
padding: EdgeInsets.all(8.0),
height: 100,
child: Row(
children: [
mywidget(),
button,
true
? Text("No button")
: ElevatedButton(onPressed: () {}, child: Text("button")),
if (true)
Text("No button")
else
ElevatedButton(onPressed: () {}, child: Text("button")),
],
),
),
),
);
}
mywidget() {
if (true)
return Text("No button");
else
return ElevatedButton(onPressed: () {}, child: Text("button"));
}
var button = true
? Text("No button")
: ElevatedButton(onPressed: () {}, child: Text("button"));
}
You can write if condition like below
if(TEXT == "text1"){
page = mainpage()
}else if(TEXT == "text2"){
page = mainpage2()
}else{
// set your code
}
Method 1
if(TEXT == "text1)
{
page = mainpage();
}
else {
page = mainpage2();
}
Method 2 (using ? operator)
TEXT == "text" ?
page = mainpage() :
page = mainpage2();
use switch case wrapped in builder method. Something like this
enum Options { text1, text2 }
Builder(
builder: (context) {
switch (option) {
case Options.text1:
return Page1();
case Options.text2:
return Page2();
default:
return Page1();
}
},
)
The best way to use if else conditoin on widget is,
Column(
children: [
if (yourCondition == true) ...[
Text(""),
] else ...[
Text(""),
],
],
),

Showing selected image in alert dialog in flutter

How can i show the selected image in my alert dialog ?
In my app, i added an alert dialog which has the camera button. When user clicks the camera button, another alert dialog asks to select file from gallery. After the user selects image file from gallery, i want to show the image in the alert dialog with the camera button, but the image shows only after reopening the alert dialog.
I have posted my code below. I am new to flutter. Please can someone help me? Thanks in advance.
class Test extends StatefulWidget {
#override
_State createState() => new _State();
}
Future<File> imageFile;
class _State extends State<Test> {
Future<void> _openDailog() async {
return showDialog<void>(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return AlertDialog(
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text('Click Photo'),
Ink(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24.0),
color: Colors.blue),
child: IconButton(
color: Colors.white,
icon: Icon(Icons.camera_alt),
onPressed: () {
_cameraOptions();
print("test");
},
),
)
],
),
content: SingleChildScrollView(
child: Container(
width: 300.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
showImage(),
InkWell(
child: Container(
margin: EdgeInsets.only(top: 8.0),
child: RaisedButton(
color: Colors.blue,
child: new Text(
"Send",
style: TextStyle(color: Colors.white),
),
onPressed: () {
Navigator.of(context).pop();
print("test");
},
),
)),
],
),
),
),
);
},
);
}
#override
Widget build(BuildContext context) {
// TODO: implement build
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FloatingActionButton(
heroTag: null,
child: Icon(Icons.insert_drive_file),
onPressed: () {
_openDailog();
},
)
],
);
}
Future<void> _cameraOptions() {
return showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
content: new SingleChildScrollView(
child: new ListBody(
children: <Widget>[
FlatButton(
onPressed: () {
pickImageFromGallery(ImageSource.gallery);
Navigator.of(context).pop();
},
color: Colors.transparent,
child: new Text(
'Select From Gallery',
textAlign: TextAlign.start,
style: new TextStyle(
decoration: TextDecoration.underline,
),
),
),
],
),
),
);
});
}
pickImageFromGallery(ImageSource source) {
setState(() {
imageFile = ImagePicker.pickImage(source: source);
});
}
Widget showImage() {
return FutureBuilder<File>(
future: imageFile,
builder: (BuildContext context, AsyncSnapshot<File> snapshot) {
if (snapshot.connectionState == ConnectionState.done &&
snapshot.data != null) {
return Image.file(
snapshot.data,
width: MediaQuery.of(context).size.width,
height: 100,
);
} else if (snapshot.error != null) {
return const Text(
'Error Picking Image',
textAlign: TextAlign.center,
);
} else {
return const Text(
'No Image Selected',
textAlign: TextAlign.center,
);
}
},
);
}
}
That is because you would need to setState() however you can't do that in an alert dialogue as it doesn't have its own state, the workaround for that would be to have the dialogue be its own stateful widget. Please check out this article as it shows how to do that. If you faced problems let me know!
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path_provider/path_provider.dart';
void main() {
runApp(new MaterialApp(
home: new MyHomePage(),
));
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _selectedIndex = 0;
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Text("StackoverFlow"),
),
body: Container(),
floatingActionButton: FloatingActionButton(
onPressed: () async {
await _dialogCall(context);
},
),
);
}
Future<void> _dialogCall(BuildContext context) {
return showDialog(
context: context,
builder: (BuildContext context) {
return MyDialog();
});
}
}
class MyDialog extends StatefulWidget {
#override
_MyDialogState createState() => new _MyDialogState();
}
class _MyDialogState extends State<MyDialog> {
String imagePath;
Image image;
#override
Widget build(BuildContext context) {
return AlertDialog(
content: new SingleChildScrollView(
child: new ListBody(
children: <Widget>[
Container(child: image!= null? image:null),
GestureDetector(
child: Row(
children: <Widget>[
Icon(Icons.camera),
SizedBox(width: 5),
Text('Take a picture '),
],
),
onTap: () async {
await getImageFromCamera();
setState(() {
});
}),
Padding(
padding: EdgeInsets.all(8.0),
),
],
),
),
);
}
Future getImageFromCamera() async {
var x = await ImagePicker.pickImage(source: ImageSource.camera);
imagePath = x.path;
image = Image(image: FileImage(x));
}
}
Try this solution with GestureDetector() .it works
onTap:()async{
var image = await ImagePicker.pickImage(
source: ImageSource.gallery).whenComplete((){
setState(() {
});
}
);
setState(() {
_image = image;
});
},