这是我所遇到问题的一个简单示例。给出以下示例,如何从Class外部获取“ counter”的值?
class Counter extends StatefulWidget {
@override
_CounterState createState() => _CounterState();
}
class _CounterState extends State<Counter> {
int counter = 0;
void increaseCount() {
setState(() => this.counter++);
print("New count = $counter");
}
Widget build(context) {
return new RaisedButton(
onPressed: increaseCount,
child: new Text('Tap To Add'),
);
}
}
答案 0 :(得分:0)
在Flutter中,通常要做的是传递一个回调函数,在该函数中,您可以传递所需的值,例如
class Counter extends StatefulWidget {
// you can use a callback function
final ValueSetter<int> callback;
Counter({this.callback});
@override
_CounterState createState() => _CounterState();
}
class _CounterState extends State<Counter> {
int counter = 0;
void increaseCount() {
setState(() => this.counter++);
print("New count = $counter");
// Here you can pass the value
widget.callback(this.counter);
}
Widget build(context) {
return new RaisedButton(
onPressed: increaseCount,
child: new Text('Tap To Add'),
);
}
}
调用小部件时,请执行以下操作:
Counter(callback: (counter){
// Here you can take some actions on counter
});
这是我所知道的最简单的方法,也可以使用其他一些模式,例如块或其他模式。
希望有帮助。
答案 1 :(得分:0)
您可以像这样使用GlobalKey:
class Counter extends StatefulWidget {
@override
final globalKey = GlobalKey<_CounterState>();
@override
_CounterState createState() => _CounterState();
}
class _CounterState extends State<Counter> {
int counter = 0;
void increaseCount() {
setState(() => counter++);
print("New count = $counter");
}
@override
Widget build(context) {
return RaisedButton(
onPressed: increaseCount,
child: Text('Tap To Add'),
);
}
}
并像这样访问计数器:
Counter counter = Counter();
int count = counter.globalKey.currentState.counter;
警告:建议不。
您正在从一个简单的包含状态过渡到几个小部件之间共享的状态。有几种更好的方法可以解决此问题。有关更多信息和解决问题的更好方法,请访问https://flutter.dev/docs/development/data-and-backend/state-mgmt。
答案 2 :(得分:0)
这只是一个示例(概念验证),用于演示我想要实现的目标。我只是希望小部件存储其值并在需要时将其提供给我(即更新数据)。另一种方法是让主程序存储该值,但我认为这不是理想的选择。
以下内容似乎起作用。简单地获取计数器的值似乎是我要做的很多事情。我希望有一个更简单的方法。代码如下:
import 'package:flutter/material.dart';
import 'counterWithState.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
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> {
CounterWithState _counterWithState =
CounterWithState(iCounter: 0, isAllowedChange: true);
FloatingActionButton _fab;
final _scaffoldKey = GlobalKey<ScaffoldState>();
@override
void initState() {
super.initState();
_fab = FloatingActionButton(
onPressed: _showSnackbar,
tooltip: 'Press to show Counter',
child: Icon(Icons.info),
);
}
_showSnackbar() {
_scaffoldKey.currentState.showSnackBar(SnackBar(
backgroundColor: Colors.blue,
content:
Text("Current value of Counter is ${_counterWithState.iCounter}")));
}
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
_counterWithState.getCounterWidget(),
],
),
),
floatingActionButton: _fab,
);
}
}
import 'package:flutter/material.dart';
class CounterWithState {
int _iCounter;
CounterWithStateInternal _counterWithStateInternal;
fnDataChanged(int iNewCounter) {
_iCounter = iNewCounter;
debugPrint("CounterWithState: New value = $_iCounter");
}
CounterWithStateInternal getCounterWidget() {
return _counterWithStateInternal;
}
CounterWithState({@required iCounter, @required bool isAllowedChange}) {
_iCounter = iCounter;
_counterWithStateInternal = CounterWithStateInternal(
GlobalKey(), this._iCounter, isAllowedChange, fnDataChanged);
}
get iCounter => _iCounter;
}
class CounterWithStateInternal extends StatefulWidget {
final int iCounter;
final bool tfAllowChange;
final Function fnDataChanged;
CounterWithStateInternal(
Key key, this.iCounter, this.tfAllowChange, this.fnDataChanged)
: super(key: key);
@override
CounterWithStateMain createState() => CounterWithStateMain();
}
class CounterWithStateMain extends State<CounterWithStateInternal> {
int _iCounter = 0;
@override
initState() {
super.initState();
_iCounter = widget.iCounter;
}
void increaseCount() {
if (widget.tfAllowChange) {
setState(() => this._iCounter++);
widget.fnDataChanged(_iCounter);
print("CounterWithStateMain: New count = $_iCounter");
}
}
Widget build(context) {
return Column(children: <Widget>[
Text("Value of counter = $_iCounter"),
SizedBox(
height: 20.0,
),
RaisedButton(
onPressed: increaseCount,
child: Text('Tap To Add'),
)
]);
}
}
答案 3 :(得分:0)
这是我先前回答的更新,目的是更好地说明我想要实现的目标。我目前在代码中使用Checkbox来存储自己的值。
这只是一个示例(概念验证),用于演示我想要实现的目标。我只是希望小部件存储其值并在需要时将其提供给我(即更新数据)。另一种方法是让主程序存储该值,但我认为这不是理想的选择。
以下内容似乎起作用。简单地获取计数器的值似乎是我要做的很多事情。我希望有一个更简单的方法。代码如下:
import 'package:flutter/material.dart';
import 'counterWithState.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
final String sTitle = 'Flutter Counter-With-State Demo';
@override
Widget build(BuildContext context) {
return MaterialApp(
title: sTitle,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: sTitle),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
CounterWithState _counterWithState;
FloatingActionButton _fab;
int _iCounterOriginal = 99;
RaisedButton _raisedButton;
SizedBox _sizedBox;
final _scaffoldKey = GlobalKey<ScaffoldState>();
@override
void initState() {
super.initState();
_fab = FloatingActionButton(
onPressed: _showSnackbar,
tooltip: 'Press to show Counter',
child: Icon(Icons.info),
);
_raisedButton = RaisedButton(
child: const Text('Update'),
color: Theme.of(context).accentColor,
elevation: 4.0,
splashColor: Colors.blueGrey,
onPressed: () {
_iCounterOriginal = _counterWithState.iCounter;
_counterWithState = null;
_getCounterWithState(context);
setState(() {});
});
_sizedBox = SizedBox(height: _raisedButton.height);
}
fnCounterChanged(int iCounter) {
setState(() {});
}
_showSnackbar() {
_scaffoldKey.currentState.showSnackBar(SnackBar(
backgroundColor: Colors.blue,
content:
Text("Current value of Counter is ${_counterWithState.iCounter}")));
}
@override
Widget build(BuildContext context) {
_counterWithState = _counterWithState != null
? _counterWithState
: _getCounterWithState(context);
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: Text(widget.title),
centerTitle: true,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
_counterWithState.getCounterWidget(),
_getUpdateButton(context),
],
),
),
floatingActionButton: _fab,
);
}
Widget _getUpdateButton(BuildContext context) {
return _counterWithState == null ||
_counterWithState.iCounter == _iCounterOriginal
? _sizedBox
: _raisedButton;
}
CounterWithState _getCounterWithState(context) {
if (_counterWithState == null)
_counterWithState = CounterWithState(
iCounter: _iCounterOriginal,
isAllowedChange: true,
fnNotifyChange: fnCounterChanged);
return _counterWithState;
}
}
import 'package:flutter/material.dart';
class CounterWithState {
int _iCounter;
final Function fnNotifyChange;
CounterWithStateInternal _counterWithStateInternal;
fnDataChanged(int iNewCounter) {
_iCounter = iNewCounter;
if (fnNotifyChange != null) fnNotifyChange(iNewCounter);
}
CounterWithStateInternal getCounterWidget() {
return _counterWithStateInternal;
}
CounterWithState(
{@required iCounter,
@required bool isAllowedChange,
this.fnNotifyChange}) {
_iCounter = iCounter;
_counterWithStateInternal = CounterWithStateInternal(
GlobalKey(), this._iCounter, isAllowedChange, fnDataChanged);
}
get iCounter => _iCounter;
}
class CounterWithStateInternal extends StatefulWidget {
final int iCounter;
final bool tfAllowChange;
final Function fnDataChanged;
CounterWithStateInternal(
Key key, this.iCounter, this.tfAllowChange, this.fnDataChanged)
: super(key: key);
@override
CounterWithStateMain createState() => CounterWithStateMain();
}
class CounterWithStateMain extends State<CounterWithStateInternal> {
int _iCounter;
int _iOriginalCounter;
@override
initState() {
super.initState();
_iCounter = widget.iCounter;
_iOriginalCounter = widget.iCounter;
}
void incrementCounter(int iValue) {
if (widget.tfAllowChange) {
setState(() => this._iCounter += iValue);
widget.fnDataChanged(_iCounter);
}
}
Widget build(context) {
return Column(children: <Widget>[
Text("Value of original counter = $_iOriginalCounter"),
_getSizedBox(),
Text("Value of counter = $_iCounter"),
_getSizedBox(),
RaisedButton(
onPressed: (() => incrementCounter(1)),
child: Text('Tap To Add'),
),
_getSizedBox(),
RaisedButton(
onPressed: (() => incrementCounter(-1)),
child: Text('Tap To Subtract'),
),
_getSizedBox(),
]);
}
SizedBox _getSizedBox() {
return SizedBox(height: 20.0);
}
}