Flutter 颤振-自定义小部件-如何从
这是我遇到的问题的一个简单例子。给出以下示例,如何从类外获取“counter”的值Flutter 颤振-自定义小部件-如何从,flutter,widget,Flutter,Widget,这是我遇到的问题的一个简单例子。给出以下示例,如何从类外获取“counter”的值 class Counter extends StatefulWidget { @override _CounterState createState() => _CounterState(); } class _CounterState extends State<Counter> { int counter = 0; void increaseCount() { se
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'),
);
}
}
类计数器扩展StatefulWidget{
@凌驾
_CounterState createState()=>\u CounterState();
}
类_countstate扩展状态{
int计数器=0;
无效增量计数(){
setState(()=>this.counter++);
打印(“新计数=$计数器”);
}
小部件构建(上下文){
返回新的RaisedButton(
onPressed:增加计数,
子项:新文本(“点击添加”),
);
}
}
在flatter中,您通常要做的是传递回调函数,在该函数中您可以传递所需的值,例如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'),
);
}
}
这是我所知道的最简单的方法,也可以使用其他一些模式,如bloc或其他模式。希望能有所帮助。您可以使用如下GlobalKey:
类计数器扩展StatefulWidget{
@凌驾
最终globalKey=globalKey();
@凌驾
_CounterState createState()=>\u CounterState();
}
类_countstate扩展状态{
int计数器=0;
无效增量计数(){
设置状态(()=>计数器++);
打印(“新计数=$计数器”);
}
@凌驾
小部件构建(上下文){
返回上升按钮(
onPressed:增加计数,
子项:文本(“点击添加”),
);
}
}
然后按如下方式访问计数器:
计数器计数器=计数器();
int count=counter.globalKey.currentState.counter;
警告:这是不推荐的
您正在从一个简单的、包含的状态过渡到多个小部件之间共享的状态。有几种更好的方法来解决这个问题。有关更多信息和更好的解决问题的方法,请访问。这只是一个示例(概念验证),用于演示我想要实现的目标。我只是想让小部件存储它的值,并在我需要时将其提供给我(即更新数据)。另一种选择是由主程序存储值,但我认为这并不理想
以下内容似乎有效。为了简单地获得计数器的值,我似乎要做很多事情。我希望有一个更简单的方法。代码如下:
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';
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;
}
}
导入“包装:颤振/材料.省道”;
导入“计数器状态.省道”;
void main()=>runApp(MyApp());
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回材料PP(
标题:“颤振演示”,
主题:主题数据(
主样本:颜色。蓝色,
),
主页:MyHomePage(标题:“颤振演示主页”),
);
}
}
类MyHomePage扩展StatefulWidget{
MyHomePage({Key,this.title}):超级(Key:Key);
最后的字符串标题;
@凌驾
_MyHomePageState createState()=>\u MyHomePageState();
}
类_MyHomePageState扩展状态{
抗衡状态=
计数器状态(i计数器:0,isAllowedChange:true);
浮动操作按钮_fab;
最终_scaffoldKey=GlobalKey();
@凌驾
void initState(){
super.initState();
_fab=浮动操作按钮(
按下按钮:_showSnackbar,
工具提示:“按此键可显示计数器”,
子:图标(Icons.info),
);
}
_showSnackbar(){
_scaffoldKey.currentState.showSnackBar(SnackBar(
背景颜色:Colors.blue,
内容:
Text(“计数器的当前值为${u counterWithState.iCounter}”);
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
钥匙:_scaffoldKey,
appBar:appBar(
标题:文本(widget.title),
),
正文:中(
子:列(
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
_counterWithState.getCounterWidget(),
],
),
),
浮动操作按钮:_fab,
);
}
}
导入“包装:颤振/材料.省道”;
阶级对抗状态{
国际货币基金组织;
CounterWithStateInternal _CounterWithStateInternal;
fnDataChanged(int iNewCounter){
_i计数器=不计数器;
debugPrint(“CounterWithState:New value=$\u iCounter”);
}
CounterWithStateInternalGetCounterWidget(){
返回(内部状态);;
}
计数器状态({@required iCounter,@required bool isAllowedChange}){
_i计数器=i计数器;
_counterWithStateInternal=counterWithStateInternal(
GlobalKey(),this.\u i计数器,isAllowedChange,fnDataChanged);
}
获取iCounter=>\u iCounter;
}
类CounterWithStateInternal扩展StatefulWidget{
最终国际数学家;
最后一次bool-tfAllowChange;
最终功能改变;
反陈述内部(
Key Key、this.iCounter、this.tfAllowChange、this.fndatachange)
:super(key:key);
@凌驾
CounterWithStateMain createState()=>CounterWithStateMain();
}
类CounterWithStateMain扩展状态{
int _i计数器=0;
@凌驾
initState(){
super.initState();
_iCounter=widget.iCounter;
}
无效增量计数(){
if(widget.tfAllowChange){
设置状态(()=>this.\u iCounter++);
widget.fnDataChanged(_iCounter);
打印(“CounterWithStateMain:New count=$\u iCounter”);
}
}
小部件构建(上下文){
返回列(子项:[
文本(“计数器值=$\u i计数器”),
大小盒子(
身高:20.0,
),
升起的按钮(
onPressed:增加计数,
子项:文本(“点击添加”),
)
]);
}
}
这是我之前答案的更新,以更好地说明我想要实现的目标。我目前在我的代码中使用这个概念,使用复选框来存储它自己的值
这只是一个简单的例子(概念证明)来说明我想要实现的目标。我只是想让小部件存储它的值,并在我需要时将其提供给我(即更新数据)。另一种选择是由主程序存储值,但我认为这并不理想
以下内容似乎有效。它似乎比我高很多
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'),
)
]);
}
}
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);
}
}