为了测试BloC设计模式,我从基本的Flutter示例开始。 StreamBuilder内部的胺化(比例类型)不起作用。
这是项目的源代码:https://github.com/fabienbellanger/flutter_bloc_example。
仅在加载小部件时启动动画,而不是在每次计数器更改时启动。
[编辑]我希望每次点击“ +”时,计数器的字体大小都会增加。加载主页后,它只能运行一次。
IncrementBloc
import 'dart:async';
import 'package:flutter_bloc_example/src/blocs/bloc_provider.dart';
class IncrementBloc implements BlocBase {
final int _counterInitial = 0;
int counter;
///
/// Stream to handle the counter
///
StreamController<int> _counterController = StreamController<int>.broadcast();
StreamSink<int> get _inUpdate => _counterController.sink;
Stream<int> get outCounter => _counterController.stream;
///
/// Stream to handle the action on the counter
///
StreamController<String> _actionController = StreamController<String>();
StreamSink<String> get updateCounter => _actionController.sink;
///
/// Constructor
///
IncrementBloc() {
counter = _counterInitial;
_actionController.stream.listen(_handleLogic);
}
void dispose() {
_actionController.close();
_counterController.close();
}
void _handleLogic(String data) {
if (data == 'add') {
counter = counter + 1;
} else {
if (counter == 0) {
counter = 0;
} else {
counter = counter - 1;
}
}
_inUpdate.add(counter);
}
}
CounterHomePage
import 'package:flutter/material.dart';
import 'package:flutter_bloc_example/src/blocs/bloc_provider.dart';
import 'package:flutter_bloc_example/src/blocs/increment_bloc.dart';
import 'package:flutter_bloc_example/src/blocs/navigation_bloc.dart';
import 'package:flutter_bloc_example/src/ui/pages/tabbar_page.dart';
///
/// CounterHome class
///
class CounterHome extends StatefulWidget {
@override
_CounterHomeState createState() => _CounterHomeState();
}
class _CounterHomeState extends State<CounterHome> {
@override
Widget build(BuildContext context) {
final IncrementBloc _incrementBloc = BlocProvider.of<IncrementBloc>(context);
return Center(
child: StreamBuilder<int>(
stream: _incrementBloc.outCounter,
initialData: _incrementBloc.counter,
builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
TextCounter(
counter: snapshot.data,
),
RaisedButton(
color: Colors.orange,
textColor: Colors.white,
disabledColor: Colors.grey,
disabledTextColor: Colors.white70,
padding: const EdgeInsets.all(10.0),
child: const Text(
'Go to TabBar Page',
style: TextStyle(fontSize: 18.0),
),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) {
return BlocProvider<NavigationBloc>(
bloc: NavigationBloc(),
child: TabBarPage(),
);
}));
},
),
],
);
}),
);
}
}
class TextCounter extends StatefulWidget {
final int counter;
const TextCounter({Key key, this.counter}) : super(key: key);
@override
_TextCounterState createState() => _TextCounterState();
}
class _TextCounterState extends State<TextCounter> with SingleTickerProviderStateMixin {
AnimationController _animationController;
Animation<double> _animationSize;
int counter;
@override
void initState() {
super.initState();
counter = widget.counter;
_animationController = new AnimationController(
duration: const Duration(milliseconds: 400),
vsync: this,
);
_animationController.addListener(() {
setState(() {});
});
_animationSize = new Tween(begin: 5.0, end: 70.0).animate(_animationController);
_animationController.forward();
}
@override
void didUpdateWidget(TextCounter oldWidget) {
if (counter != widget.counter) {
setState(() {
counter = widget.counter;
print('didUpdateWidget');
});
}
super.didUpdateWidget(oldWidget);
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
double size = _animationSize?.value;
return Text(
counter.toString(),
style: TextStyle(
fontSize: size,
color: Colors.blue,
),
);
}
}
答案 0 :(得分:0)
要在streambuilder中制作过渡动画,这非常简单,您只需使用名为AnimatedSwitcher的小部件即可:
styled-components
这里,当AnimatedSwitcher的子项发生变化时,我们使用AnimatedSwitcher为过渡设置动画,默认动画为淡入淡出动画,但是您可以通过向小部件传递TransitionBuilder来轻松指定自己的动画作为参数