Предположим, у меня есть объект
class LogoDrawer extends CustomPainter {
int x;
LogoDrawer(this.x){
print('New logoDrawer object created');
_initStuff();
}
void Paint(Canvas canvas, Size size)
{
_paintStuff();
}
}
И значение x
изменяется внешне через анимацию, и метод _initStuff
может быть дорогостоящим, но не зависит от значения x
.
Если бы я тогда оживил это методом _onClick
class _SomeState extends State<SomeWidget> with TickerProviderStateMixin {
x = 0;
Widget build(BuildContext context){
return GestureDetector(
child: CustomPaint(
willChange: true,
painter: LogoDrawer(x)
),
onTap: _onClick,
);
}
void _onClick() {
_controller = AnimationController(
duration: Duration(milliseconds: 1000),
vsync: this,
);
animation = Tween(begin: 0.4, end: 0.0).animate(CurvedAnimation(
parent: _controller, curve: Curves.ease, reverseCurve: Curves.easeOut))
..addListener(() {
setState(() {
x = x+1;
});
});
_controller.forward().orCancel;
}
}
Технически это работает, но консоль продолжает печатать
Создан новый объект logoDrawer
довольно часто (не при каждой перерисовке). А это означает, что инициализации также очень часто повторяются, что сильно сказывается на ресурсах. На самом деле я бы хотел создать объект один раз, изменить значение x
с помощью анимации и выполнять только перерисовку, а не создавать новые объекты. Я имел в виду создать пользовательский художник один раз и обновить его внутреннее значение, но это, похоже, не вызывает перерисовки.
class _SomeState extends State<SomeWidget> with TickerProviderStateMixin {
x = 0;
var myPainter = LogoDrawer(x);
Widget build(BuildContext context){
return GestureDetector(
child: CustomPaint(
willChange: true,
painter: myPainter
),
onTap: _onClick,
);
}
void _onClick() {
_controller = AnimationController(
duration: Duration(milliseconds: animDuration),
vsync: this,
);
animation = Tween(begin: 0.4, end: 0.0).animate(CurvedAnimation(
parent: _controller, curve: Curves.ease, reverseCurve: Curves.easeOut))
..addListener(() {
setState(() {
x = x+1;
// OR
painter.x = x+1;
});
});
_controller.forward().orCancel;
}
}
Обратите внимание, что это общее описание моей проблемы и что реальный код, с которым я работаю, намного сложнее этого.
repaint
параметр конструктораCustomPaint
- person pskink   schedule 07.09.2020CustomPainter
сChangeNotifier
- дополнительную информацию см. в официальной документации - person pskink   schedule 09.09.2020