В этом коде я пытаюсь сделать простое возрастающее число с помощью SlideTransition
, но это работает неправильно, я мог использовать только ScaleTransition
успешно. это значит, что я хочу увеличить число с помощью SlideTransition
Пример Gif того, что я хочу создать:
пожалуйста, смотрите second
часть как анимацию
class TestScreen extends StatefulWidget {
const TestScreen({super.key});
@override
State<TestScreen> createState() => _TestScreenState();
}
class _TestScreenState extends State<TestScreen> with SingleTickerProviderStateMixin {
int num = 0;
late final AnimationController _animationController = AnimationController(
duration: Duration(milliseconds: 750),
vsync: this)
..forward();
static final offset1 = Tween<Offset>(begin: Offset.zero, end: Offset(0, -1));
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Container(
width: double.infinity,
height: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
AnimatedSwitcher(
duration: Duration(milliseconds: 1000),
transitionBuilder: (child, animation) => SlideTransition(
position: (offset1).animate(animation),
child: child,
),
child: Text(
key: ValueKey(num),
'$num',
style: TextStyle(color: Colors.black, fontSize: 64.0),
),
),
ElevatedButton(
onPressed: () {
setState(() {
num++;
});
},
child: Text('increment'),
),
],
),
),
);
}
}
он работает, как показал pskink, но перекрывается для события быстрого нажатия.
я имею в виду, что вы не можете использовать приватные AnimationController _animationController
для анимации ваших виджетов
@pskink есть ли аналог того, что я хочу создать? например, библиотека, я пытаюсь сделать простую анимацию в виде эффекта слайда при изменении числа
AnimatedSwitcher
достаточно гибкий, чтобы делать различные переходы - просто используйте transitionBuilder
так, как я сделал это в сущности
@pskink, но это работает неправильно
вы запустили код, который я разместил? что не работает правильно?
@pskink да, я обновил свой код, проблема заключается в том, что при увеличении числа отображается предыдущее число, я не могу скрыть или установить эффект непрозрачности
Давайте продолжим обсуждение в чате.
ваш offset1
неверен, проверьте gist.github.com/pskink/…
@pskink Я посоветовал вам вставить GIF в сообщение, я обновил сообщение как то, что я хочу иметь, пожалуйста, смотрите часть second
как анимацию этого
все, что вам нужно, находится внутри метода digitMapper, внимательно проверьте его
@pskink я не понимаю, как решить эту проблему
import 'dart:async';
import 'package:flutter/material.dart';
void fileMain() {
runApp(
const MaterialApp(
home: MyApp(),
),
);
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
late AnimationController animatedController;
late Timer timer;
double milliseconds = 0;
@override
void initState() {
animatedController = AnimationController.unbounded(
vsync: this,
);
super.initState();
timer = Timer.periodic(const Duration(milliseconds: 500), (timer) {
milliseconds += 500;
animatedController.animateTo(
milliseconds,
duration: const Duration(milliseconds: 500),
);
});
}
@override
void dispose() {
animatedController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Padding(
padding: const EdgeInsets.only(left: 120),
child: AnimatedBuilder(
animation: animatedController,
builder: (context, child) {
final value = (animatedController.value / 100).ceil() / 10;
final map = value.toString().trim().split(".");
final animatedLetters = map[0].split("");
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
height: 10,
width: 10,
decoration: const BoxDecoration(
color: Colors.red, shape: BoxShape.circle)),
...animatedLetters
.asMap()
.map(
(key, value) => MapEntry(
key,
AnimatedLetter(
key: ValueKey(key),
letter: value,
),
),
)
.values
.toList(),
Text(
'.${map[1]}',
),
],
);
},
),
),
),
);
}
}
class AnimatedLetter extends StatefulWidget {
const AnimatedLetter({super.key, this.letter});
final String? letter;
@override
State<AnimatedLetter> createState() => _AnimatedLetterState();
}
class _AnimatedLetterState extends State<AnimatedLetter>
with SingleTickerProviderStateMixin {
AnimationController? controller;
String? currentLetter;
String? prevLetter;
@override
void initState() {
controller = AnimationController(
duration: const Duration(milliseconds: 300),
vsync: this,
);
currentLetter = widget.letter;
prevLetter = widget.letter;
super.initState();
}
@override
void didUpdateWidget(AnimatedLetter oldWidget) {
if (widget.letter != oldWidget.letter) {
setState(() {
prevLetter = oldWidget.letter;
currentLetter = widget.letter;
controller!
..reset()
..forward();
});
}
super.didUpdateWidget(oldWidget);
}
@override
Widget build(BuildContext context) {
return SizedBox(
child: AnimatedBuilder(
animation: controller!,
builder: (_, __) {
return Stack(
alignment: Alignment.centerRight,
children: [
Transform.translate(
offset: Offset(0, controller!.value * 20),
child: Opacity(
opacity: 1 - controller!.value,
child: Text(
prevLetter!,
textAlign: TextAlign.center,
),
),
),
Transform.translate(
offset: Offset(0, -20 + controller!.value * 20),
child: Opacity(
opacity: controller!.value,
child: Text(
currentLetter!,
textAlign: TextAlign.center,
),
),
),
],
);
}),
);
}
}
transitionBuilder
передает анимацию, которую вы должны использовать, см. gist.github.com/pskink/…