gpt4 book ai didi

flutter - Bloc 流未正确更新

转载 作者:IT王子 更新时间:2023-10-29 07:20:25 28 4
gpt4 key购买 nike

这是对以下内容的直接跟进:Bloc architecture "the getter x was called on null."由@nonybrighto 解决

现在的问题是,虽然我不再从应用程序中收到任何错误,但由于颜色没有更新,它们只是保持蓝色,所以逻辑在某处失败了。如果我调用:colorBloc.changeColor();从回调到子项(下拉菜单)本身,或直接从父项,它实际上并没有更新这些小部件按钮的颜色。它们总是蓝色的。

我还需要做些什么才能让我的按钮小部件实际更新吗?

是否需要任何其他信息?

编辑:父类和子类,以及我如何尝试使用 bloc。

dropdownmenu.dart

import 'package:flutter/material.dart';
import 'dart:math';
import 'package:ultimate_mtg/model/colorBloc.dart';
import 'package:ultimate_mtg/model/blocprovider.dart';

// ignore: camel_case_types
class dropDownMenu extends StatefulWidget {
final Function() onPressed;
final String tooltip;
final IconData icon;
final _callback;

dropDownMenu({Key key, this.onPressed, this.tooltip, this.icon, @required void singlePlayerCallbacks(String callBackType), @required StatefulWidget styleMenu } ):
_callback = singlePlayerCallbacks;

@override
dropDownMenuState createState() => dropDownMenuState();
}

// ignore: camel_case_types
class dropDownMenuState extends State<dropDownMenu>
with SingleTickerProviderStateMixin {
bool isOpened = false;
AnimationController _animationController;
Animation<double> _translateButton;
Curve _curve = Curves.easeOut;
double _fabHeight = 58;
double menuButtonSize = 55;
Color menuButtonTheme;
ColorBloc colorBloc = ColorBloc();

@override
initState() {
_animationController =
AnimationController(vsync: this, duration: Duration(milliseconds: 600))
..addListener(() {
setState(() {});
});
_translateButton = Tween<double>(
begin: 0.0,
end: _fabHeight,
).animate(CurvedAnimation(
parent: _animationController,
curve: Interval(
0.0,
1.0,
curve: _curve,
),
));
super.initState();
}

@override
dispose() {
_animationController.dispose();
colorBloc.dispose();
super.dispose();
}

animate() {
if (!isOpened) {
_animationController.forward();
} else {
_animationController.reverse();
}
isOpened = !isOpened;
}

Widget backgroundColour() {
return StreamBuilder(
initialData: Colors.blue,
stream: colorBloc.colorStream,
builder: (BuildContext context, snapShot) => Container(
width: menuButtonSize,
height: menuButtonSize,
child: RawMaterialButton(
shape: CircleBorder(),
fillColor: Colors.black,
elevation: 5.0,
onPressed: (){},
child: Container(
height: menuButtonSize - 3,
width: menuButtonSize - 3,
decoration: BoxDecoration(
color: snapShot.data,
shape: BoxShape.circle,
),
child: Image.asset(
'lib/images/background_colour.png',
scale: 4,
),
),
),
),
);
}

Widget toggle() {
return Transform.rotate(
angle: _animationController.value * (pi * 2),
child: Container(
width: menuButtonSize,
height: menuButtonSize,
child: RawMaterialButton(
shape: CircleBorder(),
fillColor: Colors.black,
elevation: 5.0,
onPressed: animate,
child: SizedBox(
height: menuButtonSize - 3,
width: menuButtonSize - 3,
child: Image.asset('lib/images/ic_launcher.png'),
),
),
),
);
}

@override
Widget build(BuildContext context) {
return Stack(
children: <Widget> [
BlocProvider(
bloc: ColorBloc(),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Stack(
children: <Widget>[
Transform(
transform: Matrix4.translationValues(
0,
_translateButton.value,
0,
),
child: backgroundColour(),
),
toggle(),
],
),
],
),
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
height: menuButtonSize,
width: menuButtonSize,
child: Opacity(
opacity: 0.0,
child: FloatingActionButton(
heroTag: null,
onPressed: animate,
),
),
),
SizedBox(
height: 3.0,
),
Container(
height: menuButtonSize,
width: menuButtonSize,
child: Opacity(
opacity: 0.0,
child: FloatingActionButton(
heroTag: null,
onPressed: isOpened == true? (){
widget?._callback('background');
} : () {},
),
),
),
],
),
],
);
}
}

singleplayer.dart

import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:ultimate_mtg/dropdownmenu.dart';
import 'package:ultimate_mtg/model/colorBloc.dart';

class SinglePlayerMode extends StatefulWidget {
@override
SinglePlayerModeParentState createState() => SinglePlayerModeParentState();
}

class SinglePlayerModeParentState extends State<SinglePlayerMode> {

ColorBloc colorBloc = ColorBloc();

@override
void initState() {
super.initState();
SystemChrome.setEnabledSystemUIOverlays([]);
SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft,]);
Screen.keepOn(true);
}

@override
dispose() {
colorBloc.dispose();
super.dispose();
}

_changeColourButton() {
colorBloc.changeColor();
}

@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () => _exitApp(context),
child: Scaffold(
body: Container(
child: Row(
children: <Widget> [
FloatingActionButton(
backgroundColor: Colors.blue,
heroTag: null,
onPressed: _changeColourButton,
child: Text(
'change',
),
),
dropDownMenu(
singlePlayerCallbacks: callBacks,
),
],
),
),
),
);
}
}

这基本上就是我尝试做的方式。

最佳答案

我在代码中做了一些修改和注释。无法对其进行测试以确保其正常工作,因此请尝试一下。

单人游戏.dart

import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:tv_series_jokes/blocs/bloc_provider.dart';
import 'package:ultimate_mtg/dropdownmenu.dart';
import 'package:ultimate_mtg/model/colorBloc.dart';

class SinglePlayerMode extends StatefulWidget {
@override
SinglePlayerModeParentState createState() => SinglePlayerModeParentState();
}

class SinglePlayerModeParentState extends State<SinglePlayerMode> {

ColorBloc colorBloc = ColorBloc(); // our color bloc instance

@override
void initState() {
super.initState();
SystemChrome.setEnabledSystemUIOverlays([]);
SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft,]);
Screen.keepOn(true);
}

@override
dispose() {
colorBloc.dispose();
super.dispose();
}

_changeColourButton() {
colorBloc.changeColor();
}

@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () => _exitApp(context),
child: Scaffold(
body: BlocProvider<ColorBloc>( // DropDownMenu can now access the bloc with this
bloc: colorBloc,
child: Container(
child: Row(
children: <Widget> [
FloatingActionButton(
backgroundColor: Colors.blue,
heroTag: null,
onPressed: _changeColourButton,
child: Text(
'change',
),
),
dropDownMenu(
singlePlayerCallbacks: callBacks,
),
],
),
),
),
),
);
}
}

DropDownMenu.dart

import 'package:flutter/material.dart';
import 'dart:math';
import 'package:ultimate_mtg/model/colorBloc.dart';
import 'package:ultimate_mtg/model/blocprovider.dart';

// ignore: camel_case_types
class dropDownMenu extends StatefulWidget {
final Function() onPressed;
final String tooltip;
final IconData icon;
final _callback;

dropDownMenu({Key key, this.onPressed, this.tooltip, this.icon, @required void singlePlayerCallbacks(String callBackType), @required StatefulWidget styleMenu } ):
_callback = singlePlayerCallbacks;

@override
dropDownMenuState createState() => dropDownMenuState();
}

// ignore: camel_case_types
class dropDownMenuState extends State<dropDownMenu>
with SingleTickerProviderStateMixin {
bool isOpened = false;
AnimationController _animationController;
Animation<double> _translateButton;
Curve _curve = Curves.easeOut;
double _fabHeight = 58;
double menuButtonSize = 55;
Color menuButtonTheme;
ColorBloc colorBloc; // we no longer create the instance here.

@override
initState() {
_animationController =
AnimationController(vsync: this, duration: Duration(milliseconds: 600))
..addListener(() {
setState(() {});
});
_translateButton = Tween<double>(
begin: 0.0,
end: _fabHeight,
).animate(CurvedAnimation(
parent: _animationController,
curve: Interval(
0.0,
1.0,
curve: _curve,
),
));


colorBloc = BlocProvider.of<ColorBloc>(context); // Getting the color bloc from the widget tree
super.initState();
}

@override
dispose() {
_animationController.dispose();
super.dispose();
}

animate() {
if (!isOpened) {
_animationController.forward();
} else {
_animationController.reverse();
}
isOpened = !isOpened;
}

Widget backgroundColour() {
return StreamBuilder(
initialData: Colors.blue,
stream: colorBloc.colorStream,
builder: (BuildContext context, snapShot) => Container(
width: menuButtonSize,
height: menuButtonSize,
child: RawMaterialButton(
shape: CircleBorder(),
fillColor: Colors.black,
elevation: 5.0,
onPressed: (){},
child: Container(
height: menuButtonSize - 3,
width: menuButtonSize - 3,
decoration: BoxDecoration(
color: snapShot.data,
shape: BoxShape.circle,
),
child: Image.asset(
'lib/images/background_colour.png',
scale: 4,
),
),
),
),
);
}

Widget toggle() {
return Transform.rotate(
angle: _animationController.value * (pi * 2),
child: Container(
width: menuButtonSize,
height: menuButtonSize,
child: RawMaterialButton(
shape: CircleBorder(),
fillColor: Colors.black,
elevation: 5.0,
onPressed: animate,
child: SizedBox(
height: menuButtonSize - 3,
width: menuButtonSize - 3,
child: Image.asset('lib/images/ic_launcher.png'),
),
),
),
);
}

@override
Widget build(BuildContext context) {

return Stack(
children: <Widget> [
// Removed the BlocProvider widget here. It wasn't working anything and was creating a separate bloc instance
// I also see why you tried to make us of the blocprovider in the backgroundColour method and it gave null.Couldn't
// have worked from that context.
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Stack(
children: <Widget>[
Transform(
transform: Matrix4.translationValues(
0,
_translateButton.value,
0,
),
child: backgroundColour(),
),
toggle(),
],
),
],
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
height: menuButtonSize,
width: menuButtonSize,
child: Opacity(
opacity: 0.0,
child: FloatingActionButton(
heroTag: null,
onPressed: animate,
),
),
),
SizedBox(
height: 3.0,
),
Container(
height: menuButtonSize,
width: menuButtonSize,
child: Opacity(
opacity: 0.0,
child: FloatingActionButton(
heroTag: null,
onPressed: isOpened == true? (){
widget?._callback('background');
} : () {},
),
),
),
],
),
],
);
}
}

关于flutter - Bloc 流未正确更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55989375/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com