You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中Slide Animation未正常工作:容器滑动动画需求求助

问题分析与解决方案

你的代码问题在于布局约束和动画偏移逻辑不匹配:

  • Positioned同时设置left:0和right:10,导致外层Row的宽度被固定为屏幕宽度减10,容器的滑动范围被限制在这个窄区域内,无法实现从右下角到屏幕底部居中的效果
  • SlideTransition的Offset参数是基于容器自身尺寸的比例偏移,原代码的Offset(1,1)仅能让容器向右偏移自身宽度,和你想要的全局位置滑动逻辑不符

下面提供两种简洁的解决方法:

方案一:使用AnimatedPositioned(推荐,逻辑直观)

直接通过动画控制容器的left/right属性,实现从右下角到底部居中的滑动:

import 'package:flutter/material.dart';

class ToastPage extends StatefulWidget {
  const ToastPage({super.key});

  @override
  State<ToastPage> createState() => _ToastPageState();
}

class _ToastPageState extends State<ToastPage> {
  bool _isCentered = false;

  @override
  void initState() {
    super.initState();
    // 页面加载后自动启动动画
    WidgetsBinding.instance.addPostFrameCallback((_) {
      setState(() => _isCentered = true);
    });
  }

  @override
  Widget build(BuildContext context) {
    final screenWidth = MediaQuery.of(context).size.width;
    const containerWidth = 200.0;
    const rightMargin = 10.0;
    final centerMargin = (screenWidth - containerWidth) / 2;

    return Scaffold(
      body: SizedBox.expand(
        child: Stack(
          children: [
            MaterialButton(
              onPressed: () {
                // 先重置到右下角,再触发居中动画
                setState(() => _isCentered = false);
                Future.delayed(const Duration(milliseconds: 100), () {
                  setState(() => _isCentered = true);
                });
              },
              child: const Text("Animate"),
            ),
            AnimatedPositioned(
              duration: const Duration(seconds: 1),
              curve: Curves.easeInOut,
              bottom: 80,
              right: _isCentered ? centerMargin : rightMargin,
              left: _isCentered ? centerMargin : null,
              child: Container(
                height: 70,
                width: containerWidth,
                color: Colors.green,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

方案二:修正SlideTransition的布局与偏移计算

如果坚持使用SlideTransition,需要调整布局约束并计算正确的偏移比例:

import 'package:flutter/material.dart';

class ToastPage extends StatefulWidget {
  const ToastPage({super.key});

  @override
  State<ToastPage> createState() => _ToastPageState();
}

class _ToastPageState extends State<ToastPage>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<Offset> _animation;

  @override
  void initState() {
    _controller = AnimationController(vsync: this, duration: const Duration(seconds: 1));
    super.initState();
    _controller.forward();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final screenWidth = MediaQuery.of(context).size.width;
    const containerWidth = 200.0;
    const rightMargin = 10.0;
    // 计算需要向左滑动的距离:从右下角到居中的水平偏移量
    final moveDistance = (screenWidth - containerWidth) / 2 - rightMargin;

    _animation = Tween<Offset>(
      begin: const Offset(0, 0),
      end: Offset(-moveDistance / containerWidth, 0),
    ).animate(CurvedAnimation(parent: _controller, curve: Curves.easeInOut));

    return Scaffold(
      body: SizedBox.expand(
        child: Stack(
          children: [
            MaterialButton(
              onPressed: () {
                _controller.reset();
                _controller.forward();
              },
              child: const Text("Animate"),
            ),
            Positioned(
              bottom: 80,
              right: rightMargin,
              child: SlideTransition(
                position: _animation,
                child: Container(
                  height: 70,
                  width: containerWidth,
                  color: Colors.green,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

内容的提问来源于stack exchange,提问作者muhammed jasir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 20:43:13