Reputation: 953
I'm just picking up flutter. I'm trying out a simple tutorial which will display the face of two dice. When I click on the floating action button, it will randomise the numbers on both dice. I took it a step further to separate the FAB into another file. My problem starts when i try to pass the onPressed event to my custom FAB file from the main file.
In my rollDice method, I'm unable to call setState which complains about instance members cant be accessed from static method. Not very sure how to move on from here.
Main.dart
import 'package:flutter/material.dart';
import 'custom_floatBtn.dart';
import 'dart:math';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
final swatch = const {
50: const Color(0xff661f00),
100: const Color(0xff992e00),
200: const Color(0xffcc3d00),
300: const Color(0xffe64500),
400: const Color(0xffff4d00),
500: const Color(0xffff5e1a),
600: const Color(0xffff824d),
700: const Color(0xffffa680),
800: const Color(0xffffc9b3),
900: const Color(0xffffede6)
};
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: MaterialColor(0xffFF5722, swatch),
//primarySwatch: Colors.green,
),
home: MyHomePage(title: 'Dice Betting'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
static int leftDiceNumber = 1;
static int rightDiceNumber = 1;
static void rollDice() {
Random num = Random();
setState(() {
leftDiceNumber = num.nextInt(6) + 1;
rightDiceNumber = num.nextInt(6) + 1;
});
}
static String param = 'Roll';
static final customFloatBtn = new CustomFloatBtn(
butname: param,
onPressed: rollDice,
);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
backgroundColor: Colors.black38,
body: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Image.asset('dice$leftDiceNumber.png'),
)),
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Image.asset('dice$rightDiceNumber.png'),
)),
],
),
),
floatingActionButton: customFloatBtn
// This trailing comma makes auto-formatting nicer for build
methods.
);
}
}
CustomFloatBtn class
import 'package:flutter/material.dart';
class CustomFloatBtn extends StatelessWidget {
final String butname;
final GestureTapCallback onPressed;
CustomFloatBtn({this.butname, this.onPressed});
@override
Widget build(BuildContext context) {
return FloatingActionButton(
tooltip: 'Increment',
//child: Icon(Icons.add),
child: Text(butname),
onPressed: onPressed,
);
}
}
Upvotes: 1
Views: 890
Reputation: 267664
I am not sure why you are not using simple implementation like this. Remove static
from everywhere.
floatingActionButton: CustomFloatBtn(
butname: param,
onPressed: rollDice,
),
Update:
void rollDice() { // remove static from here
Random num = Random();
setState(() {
leftDiceNumber = num.nextInt(6) + 1;
rightDiceNumber = num.nextInt(6) + 1;
});
}
String param = 'Roll'; // remove static from here
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: CustomFloatBtn( // use CustomFloatBtn here
butname: param,
onPressed: rollDice,
),
...
}
Upvotes: 2
Reputation: 21
Make everything non-static. All your variables and functions are class level only and you will not access them outside of your class.
So, remove static everywhere from your Main.dart file and simply do what CopsOnRoad did in his answer.
Here is the modified code
import 'package:flutter/material.dart';
import 'custom_floatBtn.dart';
import 'dart:math';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
final swatch = const {
50: const Color(0xff661f00),
100: const Color(0xff992e00),
200: const Color(0xffcc3d00),
300: const Color(0xffe64500),
400: const Color(0xffff4d00),
500: const Color(0xffff5e1a),
600: const Color(0xffff824d),
700: const Color(0xffffa680),
800: const Color(0xffffc9b3),
900: const Color(0xffffede6)
};
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: MaterialColor(0xffFF5722, swatch),
//primarySwatch: Colors.green,
),
home: MyHomePage(title: 'Dice Betting'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int leftDiceNumber = 1;
int rightDiceNumber = 1;
void rollDice() {
Random num = Random();
setState(() {
leftDiceNumber = num.nextInt(6) + 1;
rightDiceNumber = num.nextInt(6) + 1;
});
}
String param = 'Roll';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
backgroundColor: Colors.black38,
body: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Image.asset('dice$leftDiceNumber.png'),
)),
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Image.asset('dice$rightDiceNumber.png'),
)),
],
),
),
floatingActionButton: CustomFloatBtn(
butname: param,
onPressed: rollDice,
);
);
}
}
Upvotes: 1