有没有一种方法可以让我在每次按下平面按钮时都能重新构建网格视图



我正在开发一个关于flutter的迷宫应用程序。我有一个由100个平面按钮组成的网格,所有按钮都以灰色开头。当按下flatButton时,如果移动是合法的,我希望它变成绿色;如果移动是非法的,我想要它变成红色(我为此使用了splashColor属性(。移动不断从非法变为合法(基于用户当前所在的位置(,所有按钮的splashColor都应该动态更新。现在,只有当我点击按钮时,按钮的splashColor才会改变。我希望每当按下任何按钮时,整个按钮的gridView都会更新其splashColor属性。已附上代码。非常感谢您的帮助!

import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'dart:math';
import 'package:flutter/scheduler.dart' show timeDilation;
//lastmove initially set to 1 for simplicity.
int lastMove=1;
class GameButton extends StatefulWidget {
final int id;
int onPath=0;
bool testOnPath(){
if (this.onPath==1){
return true;
}
else {
return false;
}
}
bool testIfLegal(lastMove){
return (((this.id-lastMove).abs()==1) ^ ((this.id-lastMove).abs()==10));
}
bool moveCheck(){
if(this.testIfLegal(lastMove) & this.testOnPath()){
return true;
}
else{
return false;
}
}
GameButton(this.id, lastMove);
@override
_GameButtonState createState() => _GameButtonState();
}
class _GameButtonState extends State<GameButton> {
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(border: Border.all(color: Colors.black)),
child: FlatButton(
color:Colors.grey,
splashColor: widget.moveCheck()?Colors.green:Colors.red,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
onPressed: () {
bool a=widget.moveCheck();
if(a){
setState(() {
lastMove=widget.id;
print("GOOD MOVE");
}
);
}
else{
print("Illegitmate Move");
}
},
),
);
}
}
class Maze extends StatefulWidget {
List<GameButton> empty_grid = [for(var i=0; i<100; i++) new GameButton(i,lastMove)];
@override
_MazeState createState() => _MazeState();
}
class _MazeState extends State<Maze> {
@override
Widget build(BuildContext context) {
}
}
void main() {
//slow down animation to give user more time
timeDilation = 3.0;
Maze maze1 = new Maze();
//filling maze manually-will be done with function in future
(maze1.empty_grid[0]).onPath = 1;
(maze1.empty_grid[10]).onPath = 1;
(maze1.empty_grid[20]).onPath = 1;
(maze1.empty_grid[30]).onPath = 1;
(maze1.empty_grid[40]).onPath = 1;
(maze1.empty_grid[50]).onPath = 1;
(maze1.empty_grid[60]).onPath = 1;
(maze1.empty_grid[70]).onPath = 1;
(maze1.empty_grid[80]).onPath = 1;
(maze1.empty_grid[90]).onPath = 1;
(maze1.empty_grid[91]).onPath = 1;
(maze1.empty_grid[92]).onPath = 1;
(maze1.empty_grid[93]).onPath = 1;
(maze1.empty_grid[94]).onPath = 1;
(maze1.empty_grid[95]).onPath = 1;
(maze1.empty_grid[96]).onPath = 1;
(maze1.empty_grid[97]).onPath = 1;
(maze1.empty_grid[98]).onPath = 1;
(maze1.empty_grid[99]).onPath = 1;
//done filling maze1
return runApp(
MaterialApp(
home: Scaffold(
backgroundColor: Colors.blue,
appBar: AppBar(
title: Text('Gorton Maze Test'),
backgroundColor: Colors.blueAccent,
),
body: Center(
child: GridView.builder(
itemCount: 100,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 10, crossAxisSpacing: 0, mainAxisSpacing: 0),
shrinkWrap: true,
itemBuilder: (BuildContext context, int index){
return maze1.empty_grid[index];
},
)
),
),
)
);
}

是。如果使用StreamController包装,则可以更新整个GridView。

另一方面,我不认为在主课上什么都做是个好主意。为了更容易,您应该拆分类和函数。它会让你的代码更干净。

body: HomePage()),

在主页中,我使用有状态小部件的原因更多。

class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
StreamController _controller;
@override
void initState() {
super.initState();
_controller = new StreamController();
}
@override
void dispose() {
_controller.close();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Center(
child: StreamBuilder(
stream: _controller.stream,
builder: (_, __) {
return GridView.builder(
itemCount: 100,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 10,
crossAxisSpacing: 0,
mainAxisSpacing: 0),
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return maze1.empty_grid[index];
},
);
}));
}
}

每当你想更新你的网格视图时。您可以添加具有新值的StreamController

_controller.add(null);

希望这个想法能对你有所帮助。

使用现有的设计,您可以通过在GameButton中定义一个回调来实现它,该回调指向Maze类中的一个方法。每次在更改按钮颜色后按下按钮时,都会将回调调用到Maze类中,在该类中也可以更改网格颜色。Sudo代码:

class GameButton extends StatefulWidget {
final VoidCallback clickCallback
GameButton(this.id, lastMove, this.clickCallback);
.....
}
class Maze extends StatefulWidget {
List<GameButton> empty_grid = [for(var i=0; i<100; i++) new GameButton(i,lastMove, onButtonPressed)];
@override
_MazeState createState() => _MazeState();
void onButtonPressed(){
// change grid color based on index
}
}
class _MazeState extends State<Maze> {
@override
Widget build(BuildContext context) {
}
}

您可以通过调用setstate方法来实现。

在编写完逻辑后单击按钮时,请使用setstate方法。基本上setstate将重建屏幕。这样你就可以做这样的事了。

相关内容

最新更新