Flutter: How to pass variables from StatelessWidget to StatefulWidget - android

The problem is that I cannot pass the values of my own class ForceSelection values from another screen to another screen's StatefulWidget. It works fine in StatelessWidget. I have tried to learn from this flutter tutorial: https://flutter.dev/docs/cookbook/navigation/passing-data#4-navigate-and-pass-data-to-the-detail-screen
I have this kind of class in levelSelection.dart
class ForceSelection {
final String forceSelection;
final String langSelection;
ForceSelection(this.forceSelection, this.langSelection);
}
I am trying to pass the values to next file PlayQuiz.dart
Game(forceSelection: ForceSelection('maa', 'fin'))
game.dart looks like this:
class Game extends StatelessWidget {
final ForceSelection forceSelection;
Game({Key key, #required this.forceSelection}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: forceSelection.langSelection, // TODO should work and change later
theme: new ThemeData(
primaryColor: Colors.white,
),
home: PlayQuiz(),
);
}
}
And I want to pass the ForceSelection values to PlayQuiz()
class PlayQuizState extends State<PlayQuiz> {
Game.forceSelection // <--- How can I get the value out of here?
}
class PlayQuiz extends StatefulWidget {
#override
PlayQuizState createState() => new PlayQuizState();
}
The whole code can be found here: https://pastebin.com/nKssz42R
and also levelSelection.dart: https://pastebin.com/8QbBD0A2

Try this code
Added forceSelecton argument in PlayQuiz()
class Game extends StatelessWidget {
final ForceSelection forceSelection;
Game({Key key, #required this.forceSelection}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: forceSelection.langSelection, // TODO should work and change later
theme: new ThemeData(
primaryColor: Colors.white,
),
home: PlayQuiz(forceSelection),
);
}
}
In Play Quiz
class PlayQuiz extends StatefulWidget {
final ForceSelection forceSelection;
PlayQuiz(this.forceSelection);
#override
PlayQuizState createState() => new PlayQuizState(forceSelection);
}
In PlayQuizState
class PlayQuizState extends State<PlayQuiz> {
ForceSelection forceSelection;
PlayQuizState(ForceSelection forceSelection) {
this.forceSelection = forceSelection;
}
}

Related

When I open my flutter app it always shows Sign In screen for few seconds, even if I already signed In in my last session. And after that Main page?

final _navigatorKey = GlobalKey<NavigatorState>();
class MainApp extends StatefulWidget {
const MainApp({Key? key}) : super(key: key);
#override
_MainAppState createState() => _MainAppState();
}
class _MainAppState extends State<MainApp> {
#override
Widget build(BuildContext context) {
return GetMaterialApp(
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
navigatorKey: _navigatorKey,
color: Colors.white,
getPages: router.routes,
initialRoute: SignInPageRoute,
routingCallback: (routing) {
final _navigationService = locator<NavigationService>();
final _authService = locator<AuthService>();
if (routing!.current == SignInPageRoute) {
WidgetsBinding.instance!.addPostFrameCallback(
(_) {
bool isLoggedIn = _authService.isLoggedIn();
if (isLoggedIn) {
_navigationService.offAllTo(MainPageRoute);
} else {
return;
}
},
);
}
});
}
}
try with this
bool isLoggedIn = await _authService.isLoggedIn();

showing black screen on backpress Flutter

I am using Webview with WillPopScope, webview internal back button is working fine but on the first page back press is not working.
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: SafeArea(child: MyHomePage()),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
InAppWebViewController _controller;
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () => canGoBack(context),
child: Scaffold(
body: InAppWebView(
initialUrlRequest:
URLRequest(url: Uri.parse("https://www.google.com/")),
onWebViewCreated: onWebviewCreated,
),
),
);
}
void onWebviewCreated(InAppWebViewController controller) {
_controller = controller;
}
canGoBack(BuildContext context) async {
if (await _controller.canGoBack()) {
_controller.goBack();
return Future.value(false);
} else {
return Future.value(true);
}
}
}
tried with
canGoBack(BuildContext context) async {
if (await _controller.canGoBack()) {
_controller.goBack();
return Future.value(false);
} else {
Navigator.pop(context, true);
return Future.value(false);
}
}
the issue is showing the black if there is no webview history.
You don't have any previous root and you're using
Navigator.pop(context, true); // in canGoBack function
That's cause to issue. Remove that line and it will work.

how can progress-bar listen value changes using flutter provider and update another widget?

**this is my provider **
MultiProvider(
child: MyApp(),
providers: [
ChangeNotifierProvider(create: (BuildContext context)=> Downloads(),),)]
***this class implements notifylistner when i print out _progress it all works properly
but the ui wiget does not rebuid to give out the outputs ***
class Downloads extends ChangeNotifier {
int _progress= 0;
int get progress => _progress;
void setProgress(int p) {
_progress = p;
notifyListeners();
}
}
i have removed progress-bar widget to make it simple instead show output value
class FileDownload extends StatelessWidget {
const FileDownload({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(body: progessUi());
}
}
class progessUi extends StatelessWidget {
const progessUi({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
final model = Provider.of<Downloads>(context);
return Container(child: Text(model.progress.toString()));
}
}
*this just a snippet where the calls to the Download function are made *
if (message['event'] == EV_PROGRESS) {
Downloads().setProgress(message['progress']);
}
if (message['event'] == EV_DONE) {
Downloads().setProgress(100);
}

How do I access a method of the state objects for a list of stateful widgets? (Flutter)

class Astate extends State<A>
{
List b=new List<B>();
#override
Widget build(BuildContext context){
b.add(B());
//how do I access theMethod() for the state object for b[0]?
}
}
class B extends StatefulWidget
{
#override
Bstate createState() => Bstate();
}
class Bstate extends State<B>
{
theMethod()
{
//some content
}
#override
Widget build(BuildContext context) {
}
}
Is there a way to access the theMethod() using b[0] from it's corresponding state object?
If not, is there another way to achieve the same?
You can use a GlobalKey with the Widget's state to access the child Widget's methods:
class Main extends StatefulWidget {
#override
_MainState createState() => _MainState();
}
class _MainState extends State<Main> {
GlobalKey<_HomeState> _key = GlobalKey();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('StackOverflow'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Home(key: _key),
RaisedButton(
onPressed: () => _key.currentState.changeText('new text'),
child: Text('Change text'),
)
],
)
);
}
}
class Home extends StatefulWidget {
Home({Key key}) : super(key: key);
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
String text = 'initial text';
#override
Widget build(BuildContext context) {
return Center(
child: Text(text)
);
}
void changeText(String newText){
setState(() {
text = newText;
});
}
}

Show running clock on flutter

I wanted to know if there is any way to show a real time clock in dart?
Date and time (e.g 11/14/2018 19:34) and the time will continue to run.
Time can be taken from the device itself.
The below uses the intl plugin to format the time into MM/dd/yyyy hh:mm:ss. Make sure to update your pubspec.yaml.
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Time Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Time Demo'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String _timeString;
#override
void initState() {
_timeString = _formatDateTime(DateTime.now());
Timer.periodic(Duration(seconds: 1), (Timer t) => _getTime());
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Text(_timeString),
),
);
}
void _getTime() {
final DateTime now = DateTime.now();
final String formattedDateTime = _formatDateTime(now);
setState(() {
_timeString = formattedDateTime;
});
}
String _formatDateTime(DateTime dateTime) {
return DateFormat('MM/dd/yyyy hh:mm:ss').format(dateTime);
}
}
Simplest solution:
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class ClockWidget extends StatelessWidget {
const ClockWidget({super.key});
#override
Widget build(BuildContext context) {
return StreamBuilder(
stream: Stream.periodic(const Duration(seconds: 1)),
builder: (context, snapshot) {
return Text(DateFormat('MM/dd/yyyy hh:mm:ss').format(DateTime.now()));
},
);
}
}
Put it anywhere you like.
This is the same code which Albert had given, but in case you don't want to use the intl package, you can make these changes to this code:
import 'package:flutter/material.dart';
import 'dart:async';
void main () => runApp(MyApp());
class MyApp extends StatelessWidget{
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(primarySwatch: Colors.red),
home: FlutterTimeDemo(),
);
}
}
class FlutterTimeDemo extends StatefulWidget{
#override
_FlutterTimeDemoState createState()=> _FlutterTimeDemoState();
}
class _FlutterTimeDemoState extends State<FlutterTimeDemo>
{
String _timeString;
#override
void initState(){
_timeString = "${DateTime.now().hour} : ${DateTime.now().minute} :${DateTime.now().second}";
Timer.periodic(Duration(seconds:1), (Timer t)=>_getCurrentTime());
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Fluter Test'),),
body:Center(
child: Text(_timeString, style: TextStyle(fontSize: 30),),
),
);
}
void _getCurrentTime() {
setState(() {
_timeString = "${DateTime.now().hour} : ${DateTime.now().minute} :${DateTime.now().second}";
});
}
}

Categories

Resources