Keyboard opens up automatically on setState() - android

I am building a mobile application using flutter. The app has a homepage with an AnimatedIndexedStack. To switch to another screen I simply change the index. If I run the app, I can switch to any screen without any problem. However, if I switch to a screen with a textfield and tap on the textfield to edit. Now after cancelling the keyboard, if I switch to any other screen, the keyboard pops up automatically when there are no textfields on the screens and I am not tapping on any textfield. Regardless of the start screen and the end screen, the keyboard pops up automatically after changing the index.
The animated indexed stack looks like this:
import 'package:flutter/material.dart';
class AnimatedIndexedStack extends StatefulWidget {
final int index;
final List<Widget> children;
const AnimatedIndexedStack({
Key? key,
required this.index,
required this.children,
}) : super(key: key);
#override
_AnimatedIndexedStackState createState() => _AnimatedIndexedStackState();
}
class _AnimatedIndexedStackState extends State<AnimatedIndexedStack>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _animation;
int _index = 0;
#override
void initState() {
_controller = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 250),
);
_animation = Tween(begin: 0.0, end: 1.0).animate(
CurvedAnimation(
parent: _controller,
curve: Curves.ease,
),
);
_index = widget.index;
_controller.forward();
super.initState();
}
#override
void didUpdateWidget(AnimatedIndexedStack oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.index != _index) {
_controller.reverse().then((_) {
setState(() => _index = widget.index);
_controller.forward();
});
}
}
#override
void dispose() {
_controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _animation,
builder: (context, child) {
return Opacity(
opacity: _controller.value,
child: child,
);
},
child: IndexedStack(
index: _index,
children: widget.children,
),
);
}
}
homepage looks like this:
class Homepage extends StatefulWidget {
const Homepage({Key? key}) : super(key: key);
#override
_HomepageState createState() => _HomepageState();
}
class _HomepageState extends State<Homepage> {
var _currentIndex = 0;
final _homeIndex = 0;
final _titles = ['Home', 'New Booking', 'Trips', 'Payment History', 'Support', 'Profile'];
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
var _bookingStep = 0;
#override
void initState() {
_currentIndex = _homeIndex;
super.initState();
}
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async => _onWillPop(),
child: Scaffold(
key: scaffoldKey,
extendBody: true,
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
drawer: AppDrawer(selectedIndex: _currentIndex, onItemTap: (index) {
setState(() {
_currentIndex = index;
});
scaffoldKey.currentState!.closeDrawer();
},),
body: SafeArea(
bottom: false,
child: AnimatedIndexedStack(
index: _currentIndex,
children: [
const BookingsScreen(),
NewBookingScreen(onExit: () {
setState(() {
_currentIndex = 0;
});
}, bookingStep: _bookingStep, nextStep: () {
setState(() {
_bookingStep = _bookingStep + 1;
});
},),
const Trips(),
const PaymentHistoryScreen(),
SupportScreen(),
const ProfileScreen()
],
)
),
),
);
}
}

Try adding this to all screens where you have the issue,
FocusManager.instance.primaryFocus?.unfocus()

Related

Multiple widgets use the same global key , A globalkey can only be specified on one widget at a time in the widget tree

when I am using this inherited widget sometimes I had getting the issue , multiple widgets using same global key , I don't know why it shows the issue , some times in the release build app shows a full black screen , is this black screen shown because of this issue?, anyone know please help I'm new to flutter
class StateWidget extends StatefulWidget {
final Widget child;
const StateWidget({
Key? key,
required this.child,
}) : super(key: key);
#override
_StateWidgetState createState() => _StateWidgetState();
}
class _StateWidgetState extends State<StateWidget> {
CoreState state = CoreState();
void strengthCompleted(bool strengthCompleted) {
final newState = state.copy(strengthCompleted: strengthCompleted);
setState(() => state = newState);
}
void startExerciseClicked(bool startExerciseClicked) {
final newState = state.copy(startExerciseClicked: startExerciseClicked);
setState(() => state = newState);
}
void sessionCompleted(bool sessionCompleted) {
final newState = state.copy(sessionCompleted: sessionCompleted);
setState(() => state = newState);
}
void sessionValue(String sessionValue) {
final newState = state.copy(sessionValue: sessionValue);
setState(() => state = newState);
}
void recoveryDay(String recoveryDay)
{
final newState = state.copy(recoveryDay: recoveryDay);
setState(() => state = newState);
}
#override
Widget build(BuildContext context) {
return StateInheritedWidget(
child: widget.child,
state: state,
stateWidget: this,
);
}
}
class StateInheritedWidget extends InheritedWidget {
final CoreState state;
final _StateWidgetState stateWidget;
const StateInheritedWidget({
Key? key,
required Widget child,
required this.state,
required this.stateWidget,
}) : super(key: key, child: child);
static _StateWidgetState of(BuildContext context) => context
.dependOnInheritedWidgetOfExactType<StateInheritedWidget>()!
.stateWidget;
#override
bool updateShouldNotify(StateInheritedWidget oldWidget) =>
oldWidget.state != state;
}
here below I am showing the error log after getting this issue
here I am showing the mainScreen code
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
class MainScreen extends StatefulWidget {
MainScreen(
{Key? key})
: super(key: key);
#override
State<MainScreen> createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> with WidgetsBindingObserver {
#override
void initState() {
WidgetsBinding.instance.addObserver(this);
super.initState();
}
#override
void dispose() {
// TODO: implement dispose
WidgetsBinding.instance.removeObserver(this);
_controller?.dispose();
super.dispose();
}
#override
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
// if (state == AppLifecycleState.inactive ||
// state == AppLifecycleState.detached) return;
// final appInactive = state == AppLifecycleState.inactive;
final appDetached = state == AppLifecycleState.detached;
final isBackground = state == AppLifecycleState.paused;
if (appDetached) {
}
if (isBackground) {
print('app is in background');
}
}
#override
Widget build(BuildContext context) {
final sessionCompleted =
StateInheritedWidget
.of(context)
.state
.sessionCompleted;
final exerciseCompleted =
StateInheritedWidget
.of(context)
.state
.exerciseCompleted;
final sessionValue = StateInheritedWidget
.of(context)
.state
.sessionValue;
final provider = StateInheritedWidget.of(context);
SizeConfig().init(context);
print('SizeConfig.blockSizeVertical');
print(SizeConfig.blockSizeVertical);
print('SizeConfig.blockSizeHorizontal');
print(SizeConfig.blockSizeHorizontal);
return Scaffold(
key: _scaffoldKey,
backgroundColor: Colors.white,
drawer: NavigationDrawer(),
body: SafeArea(
child: SizedBox(
height: MediaQuery
.of(context)
.size
.height,
width: MediaQuery
.of(context)
.size
.width,
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Positioned(
left: 0,
top: SizeConfig.blockSizeHorizontal * .75,
bottom: SizeConfig.blockSizeHorizontal * .75,
child: InkWell(
onTap: () {
_scaffoldKey.currentState?.openDrawer();
},
child: Container(
decoration: BoxDecoration(
color: Colors.grey[100], // border color
shape: BoxShape.circle,
),
child: Image.asset(
'assets/images/navdrawerimage.png',
width: SizeConfig.blockSizeHorizontal * 5.25,
height: SizeConfig.blockSizeHorizontal * 5.25,
),
),
),
),
],
),
),
),
),
);
}
}

How to update 100 Button's Title in Flutter

Lets say i have a button. So..
String buttonTitle = "Upload";
Above is the button title.
Now i have set this in my text of the button. When i upload something, i want this text to be Uploaded so i use setState method for that and hence the title of the button will be updated. But let's suppose i have 100s of buttons which just says Upload and later have to be changed to just Uploaded if something has been uploaded using that button, am i going to create 100 Strings here? This approach doesn't seem good enough to me. Is there a better approach for this in flutter ?
Check this widget as you expect . click on main button it will update all button state after 3 second like uploading
class MyHomePages2 extends StatefulWidget {
MyHomePages2({Key? key}) : super(key: key);
var Upload = "Upload";
#override
State<MyHomePages2> createState() => _MyHomePages2State();
}
class _MyHomePages2State extends State<MyHomePages2> {
#override
Widget build(BuildContext context) {
return ListView(
children: [
ElevatedButton(
onPressed: () {
setState(() {
widget.Upload = "upload";
});
Future.delayed(Duration(seconds: 3), () {
setState(() {
widget.Upload = "uploaded";
});
});
},
child: Text("MainUpload")),
...List.generate(
100,
(index) => Padding(
padding: const EdgeInsets.all(8.0),
child: ElevatedButton(
onPressed: () {}, child: Text("$index ${widget.Upload}")),
))
],
);
}
}
SampleCode Dartpad live code
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
int myvalue = 0;
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
#override
void initState() {
// functions().then((int value) {
// setState(() {
// myvalue = value;
// });
// future is completed you can perform your task
// });
}
Future<int> functions() async {
// do something here
return Future.value();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: MyHomePages2(),
);
}
}
class MyHomePages2 extends StatefulWidget {
MyHomePages2({Key? key}) : super(key: key);
var Upload = "Upload";
#override
State<MyHomePages2> createState() => _MyHomePages2State();
}
class _MyHomePages2State extends State<MyHomePages2> {
#override
Widget build(BuildContext context) {
return ListView(
children: [
ElevatedButton(
onPressed: () {
setState(() {
widget.Upload = "upload";
});
Future.delayed(Duration(seconds: 3), () {
setState(() {
widget.Upload = "uploaded";
});
});
},
child: Text("MainUpload")),
...List.generate(
100,
(index) => Padding(
padding: const EdgeInsets.all(8.0),
child: ElevatedButton(
onPressed: () {}, child: Text("$index ${widget.Upload}")),
))
],
);
}
}

Flutter || Scroll back to top button

In my flutter project I made a floating button that help to auto scroll to the top of the page with one click, and when it reach the top it disappear. It work perfectly. But my problem is that I need to double click in it so it can disappear I want it to automatically disappear if it reach the top. Any help is highly appreciated.
void scrollToTop(){
_controller.runJavascript("window.scrollTo({top: 0, behavior: 'smooth'});");
floatingButtonVisibility();
}
void floatingButtonVisibility() async {
int y = await _controller.getScrollY();
if(y>50){
setState(() {
buttonshow = true;
});
}else {
setState(() {
buttonshow = false;
});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter WebView'),
),
body: WebView(
initialUrl: 'https://flutter.dev',
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller = webViewController;
},
gestureRecognizers: Set()
..add(
Factory<VerticalDragGestureRecognizer>(() => VerticalDragGestureRecognizer()
..onDown = (tap) {
floatingButtonVisibility();
}))
),
floatingActionButton: Visibility(
visible: buttonshow,
child: FloatingActionButton(
onPressed: () {
scrollToTop();
},
backgroundColor: Colors.blue,
child: const Icon(Icons.navigation),
),
),
);
}
}
Here is my solution.
Register 'window.onscroll' in to send webview's scroll position to outside of Webview widget.
Register receiver to receive event from webview.
If scroll is 0, change 'buttonshow' value and rebuild widget.
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
WebViewController _controller;
bool buttonshow = false;
#override
void initState() {
super.initState();
}
void scrollToTop() {
_controller.evaluateJavascript(
"window.onscroll = function () {scrollEventChannel.postMessage(window.scrollY)};");
_controller
.evaluateJavascript("window.scrollTo({top: 0, behavior: 'smooth'});");
floatingButtonVisibility();
}
void floatingButtonVisibility() async {
int y = await _controller.getScrollY();
if (y > 50) {
setState(() {
buttonshow = true;
});
} else {
setState(() {
buttonshow = false;
});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter WebView'),
),
body: WebView(
initialUrl: 'https://flutter.dev',
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller = webViewController;
},
javascriptChannels: {
JavascriptChannel(
name: 'scrollEventChannel',
onMessageReceived: (JavascriptMessage message) {
print('>>>>: ${message.message}');
if (message.message == '0') {
setState(() {
buttonshow = false;
});
}
}),
},
gestureRecognizers: Set()
..add(Factory<VerticalDragGestureRecognizer>(
() => VerticalDragGestureRecognizer()
..onDown = (tap) {
floatingButtonVisibility();
}))),
floatingActionButton: Visibility(
visible: buttonshow,
child: FloatingActionButton(
onPressed: () {
scrollToTop();
},
backgroundColor: Colors.blue,
child: const Icon(Icons.navigation),
),
),
);
}
}
I changed button show trigger from gestureRecognizers to postion event.
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
WebViewController _controller;
bool buttonshow = false;
#override
void initState() {
super.initState();
}
void scrollToTop() {
_controller
.evaluateJavascript("window.scrollTo({top: 0, behavior: 'smooth'});");
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter WebView'),
),
body: WebView(
initialUrl: 'https://flutter.dev',
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller = webViewController;
},
onPageFinished: (String url) async {
_controller.evaluateJavascript(
"window.onscroll = function () {scrollEventChannel.postMessage(window.scrollY)};");
},
javascriptChannels: {
JavascriptChannel(
name: 'scrollEventChannel',
onMessageReceived: (JavascriptMessage message) {
print('>>>>: ${message.message}');
int position = int.parse(message.message);
if (position == 0) {
setState(() {
buttonshow = false;
});
} else if (position > 60) {
setState(() {
buttonshow = true;
});
}
}),
},
),
floatingActionButton: Visibility(
visible: buttonshow,
child: FloatingActionButton(
onPressed: () {
scrollToTop();
},
backgroundColor: Colors.blue,
child: const Icon(Icons.navigation),
),
),
);
}
}
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget{
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Home()
);
}
}
class Home extends StatefulWidget {
#override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
ScrollController scrollController = ScrollController();
bool showbtn = false;
List<String> countries = ["USA", "United Kingdom", "China", "Russia", "Brazil",
"India", "Pakistan", "Nepal", "Bangladesh", "Sri Lanka",
"Japan", "South Korea", "Mongolia"];
#override
void initState() {
scrollController.addListener(() { //scroll listener
double showoffset = 10.0; //Back to top botton will show on scroll offset 10.0
if(scrollController.offset > showoffset){
showbtn = true;
setState(() {
//update state
});
}else{
showbtn = false;
setState(() {
//update state
});
}
});
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Scroll Back to Top Button"),
backgroundColor: Colors.redAccent
),
floatingActionButton: AnimatedOpacity(
duration: Duration(milliseconds: 1000), //show/hide animation
opacity: showbtn?1.0:0.0, //set obacity to 1 on visible, or hide
child: FloatingActionButton(
onPressed: () {
scrollController.animateTo( //go to top of scroll
0, //scroll offset to go
duration: Duration(milliseconds: 500), //duration of scroll
curve:Curves.fastOutSlowIn //scroll type
);
},
child: Icon(Icons.arrow_upward),
backgroundColor: Colors.redAccent,
),
),
body: SingleChildScrollView(
controller: scrollController, //set controller
child:Container(
child:Column(
children: countries.map((country){
return Card(
child:ListTile(
title: Text(country)
)
);
}).toList(),
)
)
)
);
}

No host specified in URI (Flutter)

So I have this code and I take an image from Internet with webscrapper, the problem is that when I try to take the image with the basic URl without the http:// behind it don't work and when I add it I don't have any error but I got a black screen on my emulator and I can't see this value of the image on my terminal even if I know the value is not null.
If someone can help I will be very greatful thank you very much !
class ContentScreen extends StatefulWidget {
const ContentScreen({Key? key}) : super(key: key);
#override
_ContentScreenState createState() => _ContentScreenState();
}
class _ContentScreenState extends State<ContentScreen> {
List<Map<String,dynamic>>? contentPages;
bool Data = false;
Future<void> getcontent() async{
final webscraper = WebScraper("https://manhuas.net/");
String TempRoute = "manhua/what-harm-would-my-girl-do-manhua/what-harm-would-my-girl-do-chapter-1/";
if (await webscraper.loadWebPage(TempRoute)){
contentPages = webscraper.getElement("div.page-break.no-gaps > img ", ["data-src"]);
setState(() {
Data = true;
});
print(contentPages);
}
}
#override
void initState() {
// TODO: implement initState
super.initState();
getcontent();
}
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: getcontent(),
builder: (context, snapshot) {
return Scaffold(
body: Data? Container(
child: ListView.builder(
shrinkWrap: true,
itemCount: contentPages!.length,
itemBuilder: (context,index ) {
return Image.network(contentPages![index]['attributes']['src'].toString().trim(),
fit: BoxFit.fitWidth,loadingBuilder: (context , child, loadingprogress){
if (loadingprogress != null) return child;
return Center(
child: CircularProgressIndicator(),
);
},);
},
)
)
: Center(
child: CircularProgressIndicator(
color: Constants.mygreen,
)
));
}
);
}
}
And this is a screen of my screen for more details:
Please check the below code it's working perfectly
import 'package:flutter/material.dart';
import 'package:web_scraper/web_scraper.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'OverlayEntry Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: ContentScreen(),
);
}
}
class ContentScreen extends StatefulWidget {
const ContentScreen({Key? key}) : super(key: key);
#override
_ContentScreenState createState() => _ContentScreenState();
}
class _ContentScreenState extends State<ContentScreen> {
List<Map<String, dynamic>>? contentPages;
bool Data = false;
Future<void> getcontent() async {
final webscraper = WebScraper("https://manhuas.net/");
String TempRoute =
"manhua/what-harm-would-my-girl-do-manhua/what-harm-would-my-girl-do-chapter-1/";
if (await webscraper.loadWebPage(TempRoute)) {
contentPages =
webscraper.getElement("div.page-break.no-gaps > img ", ["data-src"]);
setState(() {
Data = true;
});
print(contentPages);
}
}
#override
void initState() {
// TODO: implement initState
super.initState();
getcontent();
}
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: getcontent(),
builder: (context, snapshot) {
return Scaffold(
body: Data
? Container(
child: ListView.builder(
shrinkWrap: true,
itemCount: contentPages!.length,
itemBuilder: (context, index) {
return Image.network(
contentPages![index]['attributes']
['data-src']
.toString()
.trim(),
fit: BoxFit.fitWidth,
);
},
))
: Center(
child: CircularProgressIndicator(
color: Colors.green,
)));
});
}
}

Flutter - How correctly pause camera when user moved to other (preview) screen?

I need to pause camera when I move to another screen on the navigator tree in order to save battery and performance.
I tried to dispose() cameraController, but flutter doesn't re-initialize the state when it returns from another screen (which is obvious, though).
My main code to work with a camera:
#override
void initState() {
super.initState();
availableCameras().then((cameras) {
setState(() {
_firstCamera = cameras.first;
_controller = CameraController(_firstCamera, ResolutionPreset.high);
_initializeControllerFuture = _controller.initialize();
});
});
}
#override
void dispose() {
_controller?.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
body: Stack(
children: <Widget>[
FutureBuilder<void>(
future: _initializeControllerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return Stack(
alignment: FractionalOffset.center,
children: <Widget>[
new Positioned.fill(
child: _getCameraPreview(context),
),
...
],
);
} else {
return Center(child: CircularProgressIndicator());
}
},
),
Align(
alignment: Alignment.bottomCenter,
child: BottomAppBar(
color: Color.fromARGB(0, 0, 0, 0),
child: _getBottomAppBarRow(context),
),
),
],
),
);
}
_getCameraPreview(BuildContext context) {
final size = MediaQuery.of(context).size;
final deviceRatio = size.width / size.height;
return Transform.scale(
scale: _controller.value.aspectRatio / deviceRatio,
child: Center(
child: AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: CameraPreview(_controller),
),
),
);
}
Have a variable like _cameraOn = true. Show CameraPreview when it is true and not when it is false. While navigating to another screen set it to false
You could have the camera related functionality in a separate widget. So every time it is displayed it is initialized, and when it is not it's disposed.
A simple working example
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
List<CameraDescription> cameras;
Future<void> main() async {
cameras = await availableCameras();
runApp(MaterialApp(
home: CameraApp(),
));
}
class CameraApp extends StatefulWidget {
#override
_CameraAppState createState() => _CameraAppState();
}
class _CameraAppState extends State<CameraApp> {
bool _cameraOn = true;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
Expanded(
child: _cameraOn ? Camera() : Container(),
),
FlatButton(
onPressed: () {
setState(() {
_cameraOn = false;
});
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => Post())).then((res) {
setState(() {
_cameraOn = true;
});
}).catchError((err) {
print(err);
});
},
child: Text("NEXT PAGE"),
),
],
),
);
}
}
class Camera extends StatefulWidget {
#override
_CameraState createState() => _CameraState();
}
class _CameraState extends State<Camera> {
CameraController controller;
#override
void initState() {
super.initState();
controller = CameraController(cameras[0], ResolutionPreset.medium);
controller.initialize().then((_) {
if (!mounted) {
return;
}
setState(() {});
});
}
#override
Widget build(BuildContext context) {
if (!controller.value.isInitialized) {
return Container();
}
return AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: CameraPreview(controller),
);
}
#override
void dispose() {
controller?.dispose();
super.dispose();
}
}
class Post extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Text("Post"),
);
}
}
Suppose the camera controller for an instance of the camera package is defined as such:
List<CameraDescription> cameras = [];
controller = CameraController(
cameras[0],
ResolutionPreset.high,
enableAudio: false,
);
This can be used to pause the camera:
controller.pausePreview();
This can be used to resume the camera:
controller.resumePreview();

Categories

Resources