Flutter 让机架在洗牌后更新
在下面的示例中,在洗牌之后,要更新机架,最好使用什么构造 在我看来,当创建一个StatefulWidget及其相应的State对象(SO)时,您可以从别处调用的任何方法都是附加到widget本身(而不是SO)的方法 但是,为了让小部件更新其显示,SetState()方法只能放在SO的方法中。那么小部件上的方法如何调用其So上的方法呢Flutter 让机架在洗牌后更新,flutter,Flutter,在下面的示例中,在洗牌之后,要更新机架,最好使用什么构造 在我看来,当创建一个StatefulWidget及其相应的State对象(SO)时,您可以从别处调用的任何方法都是附加到widget本身(而不是SO)的方法 但是,为了让小部件更新其显示,SetState()方法只能放在SO的方法中。那么小部件上的方法如何调用其So上的方法呢 import 'package:flutter/material.dart'; List<Block> g_blocks = [Block(Color
import 'package:flutter/material.dart';
List<Block> g_blocks = [Block(Colors.red), Block(Colors.green), Block(Colors.blue)];
Rack g_rack = new Rack();
void main() => runApp(MyApp());
// This widget is the root of your application.
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
fontFamily: 'PressStart',
),
home: MyHomeScreen(),
);
}
}
class MyHomeScreen extends StatefulWidget {
MyHomeScreen({Key key}) : super(key: key);
createState() => MyHomeScreenState();
}
class MyHomeScreenState extends State<MyHomeScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Center(child: Text('Thanks for your help')),
backgroundColor: Colors.pink,
),
body: Center(
child: g_rack,
),
bottomNavigationBar: SizedBox(
height: 100.0,
child: BottomNavigationBar(
currentIndex: 0,
iconSize: 48.0,
backgroundColor: Colors.lightBlue[100],
items: [
BottomNavigationBarItem(
label: 'Shuffle',
icon: Icon(Icons.home),
),
BottomNavigationBarItem(
label: 'Shuffle',
icon: Icon(Icons.home),
),
],
onTap: (int indexOfItem) {
setState(() {
g_blocks.shuffle;
rack.updateScreen(); // ** How to get the rack to update? **
});
},
),
),
);
} // build
} // End class MyHomeScreenState
class Rack extends StatefulWidget {
@override
_rackState createState() => _rackState();
}
class _rackState extends State<Rack> {
@override
Widget build(BuildContext context) {
return Container(
height: 150.0,
color: Colors.yellow[200],
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: g_blocks),
);
}
void updateRack(){
setState(() {
g_blocks.shuffle;
});
}
}
class Block extends StatelessWidget {
final Color color;
Block(this.color);
@override
Widget build(BuildContext context) {
return Container(height:50,width:50, color: color,);
}
}
导入“包装:颤振/材料.省道”;
列出g_块=[Block(Colors.red)、Block(Colors.green)、Block(Colors.blue)];
机架g_机架=新机架();
void main()=>runApp(MyApp());
//此小部件是应用程序的根。
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回材料PP(
主题:主题数据(
fontFamily:'按开始',
),
主页:MyHomeScreen(),
);
}
}
类MyHomeScreen扩展StatefulWidget{
MyHomeScreen({Key}):超级(Key:Key);
createState()=>MyHomeScreenState();
}
类MyHomeScreenState扩展了状态{
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:中心(儿童:文本(“感谢您的帮助”),
背景颜色:Colors.pink,
),
正文:中(
孩子:g_rack,
),
底部导航栏:大小框(
高度:100.0,
子项:底部导航栏(
当前索引:0,
iconSize:48.0,
背景颜色:颜色。浅蓝色[100],
项目:[
底部导航气压计(
标签:'Shuffle',
图标:图标(Icons.home),
),
底部导航气压计(
标签:'Shuffle',
图标:图标(Icons.home),
),
],
onTap:(int indexOfItem){
设置状态(){
g_blocks.shuffle;
rack.updateScreen();//**如何获取要更新的机架**
});
},
),
),
);
}//构建
}//结束类MyHomeScreenState
类Rack扩展StatefulWidget{
@凌驾
_rackState createState()=>rackState();
}
类_rackState扩展了状态{
@凌驾
小部件构建(构建上下文){
返回容器(
高度:150.0,
颜色:颜色。黄色[200],
孩子:排(
mainAxisAlignment:mainAxisAlignment.space,
//mainAxisAlignment:mainAxisAlignment.spaceBetween,
mainAxisSize:mainAxisSize.max,
儿童:g_街区),
);
}
void updateRack(){
设置状态(){
g_blocks.shuffle;
});
}
}
类块扩展了无状态小部件{
最终颜色;
块(此颜色);
@凌驾
小部件构建(构建上下文){
返回容器(高度:50,宽度:50,颜色:颜色,);
}
}
这里是一个解决方案,我尝试将应用程序的状态管理和业务逻辑与用户界面分离
我使用了以下软件包:
- 对于域实体
- 为国家管理
1.域层:实体 我们需要两个实体来为
块的机架
建模
块
由其颜色定义
块
没有业务逻辑
机架
是块的有序列表
机架
可以进行洗牌
机架可以为(随机或给定)数量的块随机创建
3.表示层:用户界面
用户界面由四个小部件组成:
AppWidget
[无状态widget]
主页
[HookWidget]
RackWidget
[无状态Widget]
BlockWidget
[无状态widget]
如您所见,真正关心应用程序状态的唯一小部件是主页
3.1 AppWidget
3.2网页
机架
由我们的StateNotifierProvider在监视模式下提供:
final rack = useProvider(RackStateNotifier.provider.state);
机架
在读取模式下使用相同的提供程序进行处理和洗牌:
...
context.read(RackStateNotifier.provider).deal(),
...
context.read(RackStateNotifier.provider).shuffle(),
...
3.3 RackWidget
基本无状态小部件。我们使用LayoutBuilder来定义块widgets
的大小
3.4区块小部件
另一个基本的无状态小部件
完整应用程序代码
只需复制粘贴以下内容即可尝试
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
part '66053795.shuffle.freezed.dart';
Random random = Random();
void main() => runApp(ProviderScope(child: AppWidget()));
class AppWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Colors.amber,
accentColor: Colors.black87,
),
home: HomePage(),
);
}
}
class HomePage extends HookWidget {
@override
Widget build(BuildContext context) {
final rack = useProvider(RackStateNotifier.provider.state);
return Scaffold(
appBar: AppBar(
title: Row(
children: const [
Icon(Icons.casino_outlined),
SizedBox(
width: 8.0,
),
Text('Rack Shuffler'),
],
),
),
body: Center(
child: RackWidget(rack: rack),
),
bottomNavigationBar: BottomAppBar(
color: Theme.of(context).primaryColor,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
IconButton(
icon: Icon(Icons.refresh),
iconSize: 48,
onPressed: () => context.read(RackStateNotifier.provider).deal(),
),
IconButton(
icon: Icon(Icons.shuffle),
iconSize: 48,
onPressed: () =>
context.read(RackStateNotifier.provider).shuffle(),
),
],
),
),
);
}
}
class RackWidget extends StatelessWidget {
final Rack rack;
const RackWidget({Key key, this.rack}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: LayoutBuilder(
builder: (context, constraints) {
return Row(
children: rack.blocks
.map((block) => BlockWidget(
block: block,
size: constraints.biggest.width / rack.blocks.length))
.toList(),
);
},
),
);
}
}
class BlockWidget extends StatelessWidget {
final Block block;
final double size;
const BlockWidget({
Key key,
this.block,
this.size,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return SizedBox(
width: size,
height: size,
child: Padding(
padding: EdgeInsets.all(size / 10),
child: Container(
decoration: BoxDecoration(
color: block.color,
border: Border.all(color: Colors.black87, width: size / 20),
borderRadius: BorderRadius.circular(size / 15),
),
),
),
);
}
}
class RackStateNotifier extends StateNotifier<Rack> {
static final provider =
StateNotifierProvider<RackStateNotifier>((ref) => RackStateNotifier());
RackStateNotifier([Rack state]) : super(state ?? Rack.create());
void shuffle() {
state = state.shuffled;
}
void deal() {
state = Rack.create();
}
}
@freezed
abstract class Block with _$Block {
const factory Block({Color color}) = _Block;
}
@freezed
abstract class Rack implements _$Rack {
const factory Rack({List<Block> blocks}) = _Rack;
const Rack._();
static Rack create([int nbBlocks]) => Rack(
blocks: List.generate(
nbBlocks ?? 4 + random.nextInt(6),
(index) => Block(
color: Color(0x66000000 + random.nextInt(0xffffff)),
),
),
);
Rack get shuffled => Rack(blocks: blocks..shuffle());
}
import'dart:math';
进口“包装:颤振/材料.省道”;
进口“包装:颤振钩/颤振钩.省道”;
导入“package:freezed_annotation/freezed_annotation.dart”;
进口“包装:hooks_riverpod/hooks_riverpod.dart”;
第66053795部分:洗牌,冷冻,飞镖;
随机=随机();
void main()=>runApp(ProviderScope(子:AppWidget());
类AppWidget扩展了无状态Widget{
@凌驾
小部件构建(构建上下文){
返回材料PP(
debugShowCheckedModeBanner:false,
主题:主题数据(
primaryColor:Colors.琥珀色,
accentColor:Colors.black87,
),
主页:主页(),
);
}
}
类主页扩展了小部件{
@凌驾
小部件构建(构建上下文){
最终机架=useProvider(RackStateNotifier.provider.state);
返回脚手架(
appBar:appBar(
标题:世界其他地区(
儿童:康斯特[
图标(图标。赌场),
大小盒子(
宽度:8.0,
),
文本('Rack Shuffler'),
],
),
),
正文:中(
子:机架小部件(机架:机架),
),
bottomNavigationBar:BottomAppBar(
颜色:主题。背景。原色,
孩子:排(
mainAxisAlignment:mainAxisAlignment.spaceAround,
儿童:[
图标按钮(
图标:图标(Icons.refresh),
iconSize:48,
onPressed:()=>context.rea
class HomePage extends HookWidget {
@override
Widget build(BuildContext context) {
final rack = useProvider(RackStateNotifier.provider.state);
return Scaffold(
appBar: AppBar(
title: Row(
children: const [
Icon(Icons.casino_outlined),
SizedBox(
width: 8.0,
),
Text('Rack Shuffler'),
],
),
),
body: Center(
child: RackWidget(rack: rack),
),
bottomNavigationBar: BottomAppBar(
color: Theme.of(context).primaryColor,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
IconButton(
icon: Icon(Icons.refresh),
iconSize: 48,
onPressed: () => context.read(RackStateNotifier.provider).deal(),
),
IconButton(
icon: Icon(Icons.shuffle),
iconSize: 48,
onPressed: () =>
context.read(RackStateNotifier.provider).shuffle(),
),
],
),
),
);
}
}
final rack = useProvider(RackStateNotifier.provider.state);
...
context.read(RackStateNotifier.provider).deal(),
...
context.read(RackStateNotifier.provider).shuffle(),
...
class RackWidget extends StatelessWidget {
final Rack rack;
const RackWidget({Key key, this.rack}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: LayoutBuilder(
builder: (context, constraints) {
return Row(
children: rack.blocks
.map((block) => BlockWidget(
block: block,
size: constraints.biggest.width / rack.blocks.length))
.toList(),
);
},
),
);
}
}
class BlockWidget extends StatelessWidget {
final Block block;
final double size;
const BlockWidget({
Key key,
this.block,
this.size,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return SizedBox(
width: size,
height: size,
child: Padding(
padding: EdgeInsets.all(size / 10),
child: Container(
decoration: BoxDecoration(
color: block.color,
border: Border.all(color: Colors.black87, width: size / 20),
borderRadius: BorderRadius.circular(size / 15),
),
),
),
);
}
}
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
part '66053795.shuffle.freezed.dart';
Random random = Random();
void main() => runApp(ProviderScope(child: AppWidget()));
class AppWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Colors.amber,
accentColor: Colors.black87,
),
home: HomePage(),
);
}
}
class HomePage extends HookWidget {
@override
Widget build(BuildContext context) {
final rack = useProvider(RackStateNotifier.provider.state);
return Scaffold(
appBar: AppBar(
title: Row(
children: const [
Icon(Icons.casino_outlined),
SizedBox(
width: 8.0,
),
Text('Rack Shuffler'),
],
),
),
body: Center(
child: RackWidget(rack: rack),
),
bottomNavigationBar: BottomAppBar(
color: Theme.of(context).primaryColor,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
IconButton(
icon: Icon(Icons.refresh),
iconSize: 48,
onPressed: () => context.read(RackStateNotifier.provider).deal(),
),
IconButton(
icon: Icon(Icons.shuffle),
iconSize: 48,
onPressed: () =>
context.read(RackStateNotifier.provider).shuffle(),
),
],
),
),
);
}
}
class RackWidget extends StatelessWidget {
final Rack rack;
const RackWidget({Key key, this.rack}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: LayoutBuilder(
builder: (context, constraints) {
return Row(
children: rack.blocks
.map((block) => BlockWidget(
block: block,
size: constraints.biggest.width / rack.blocks.length))
.toList(),
);
},
),
);
}
}
class BlockWidget extends StatelessWidget {
final Block block;
final double size;
const BlockWidget({
Key key,
this.block,
this.size,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return SizedBox(
width: size,
height: size,
child: Padding(
padding: EdgeInsets.all(size / 10),
child: Container(
decoration: BoxDecoration(
color: block.color,
border: Border.all(color: Colors.black87, width: size / 20),
borderRadius: BorderRadius.circular(size / 15),
),
),
),
);
}
}
class RackStateNotifier extends StateNotifier<Rack> {
static final provider =
StateNotifierProvider<RackStateNotifier>((ref) => RackStateNotifier());
RackStateNotifier([Rack state]) : super(state ?? Rack.create());
void shuffle() {
state = state.shuffled;
}
void deal() {
state = Rack.create();
}
}
@freezed
abstract class Block with _$Block {
const factory Block({Color color}) = _Block;
}
@freezed
abstract class Rack implements _$Rack {
const factory Rack({List<Block> blocks}) = _Rack;
const Rack._();
static Rack create([int nbBlocks]) => Rack(
blocks: List.generate(
nbBlocks ?? 4 + random.nextInt(6),
(index) => Block(
color: Color(0x66000000 + random.nextInt(0xffffff)),
),
),
);
Rack get shuffled => Rack(blocks: blocks..shuffle());
}
import 'package:flutter/material.dart';
List<Block> g_blocks = [Block(Colors.red), Block(Colors.green),
Block(Colors.blue), Block(Colors.purple)];
GlobalKey g_key = GlobalKey();
Rack g_rack = new Rack(key: g_key);
void main() => runApp(MyApp());
// This widget is the root of your application.
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
fontFamily: 'PressStart',
),
home: MyHomeScreen(),
);
}
}
class MyHomeScreen extends StatefulWidget {
MyHomeScreen({Key key}) : super(key: key);
createState() => MyHomeScreenState();
}
class MyHomeScreenState extends State<MyHomeScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Center(child: Text('Thanks for your help')),
backgroundColor: Colors.pink,
),
body: Center(
child: g_rack,
),
bottomNavigationBar: SizedBox(
height: 100.0,
child: BottomNavigationBar(
currentIndex: 0,
iconSize: 48.0,
backgroundColor: Colors.lightBlue[100],
items: [
BottomNavigationBarItem(
label: 'Shuffle',
icon: Icon(Icons.home),
),
BottomNavigationBarItem(
label: 'Shuffle',
icon: Icon(Icons.home),
),
],
onTap: (int index) {
g_blocks.shuffle();
g_key.currentState.setState(() {
});
}
),
),
);
} // build
} // End class MyHomeScreenState
class Rack extends StatefulWidget {
Rack({Key key}) : super(key: key);
@override
_rackState createState() => _rackState();
}
class _rackState extends State<Rack> {
@override
Widget build(BuildContext context) {
return Container(
height: 150.0,
color: Colors.yellow[200],
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.max,
children: g_blocks),
);
}
void updateRack(){
setState(() {});
}
}
class Block extends StatelessWidget {
final Color color;
Block(this.color);
@override
Widget build(BuildContext context) {
return Container(height:50,width:50, color: color,);
}
}