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

Flutter年龄选择页图片缩放及切换动画实现需求

Flutter年龄输入页面交互实现方案

核心实现思路

  • 用StatefulWidget维护年龄、当前图片索引、缩放比例状态
  • 通过Slider联动年龄值,实时计算图片缩放比例
  • 基于年龄阈值切换图片,切换时触发短暂的缩小回弹动画增强交互感

完整代码示例

import 'package:flutter/material.dart';

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

  @override
  State<AgeInputPage> createState() => _AgeInputPageState();
}

class _AgeInputPageState extends State<AgeInputPage> with TickerProviderStateMixin {
  // 初始年龄
  double _currentAge = 20;
  // 图片索引:0=孩童,1=成人,2=老人
  int _currentImageIndex = 1;
  // 缩放动画控制器
  late AnimationController _scaleController;
  late Animation<double> _scaleAnimation;

  // 年龄阈值
  final int childThreshold = 12;
  final int elderThreshold = 60;

  // 基础缩放范围:年龄0对应0.8,年龄100对应1.2
  final double minScale = 0.8;
  final double maxScale = 1.2;

  @override
  void initState() {
    super.initState();
    // 初始化缩放动画控制器,用于切换图片时的回弹效果
    _scaleController = AnimationController(
      duration: const Duration(milliseconds: 300),
      vsync: this,
    );
    _scaleAnimation = Tween<double>(begin: 1.0, end: 1.0).animate(
      CurvedAnimation(parent: _scaleController, curve: Curves.easeInOut),
    );
    // 初始计算图片索引
    _updateImageIndex(_currentAge);
  }

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

  // 根据年龄更新图片索引
  void _updateImageIndex(double age) {
    int newIndex = 1;
    if (age <= childThreshold) {
      newIndex = 0;
    } else if (age >= elderThreshold) {
      newIndex = 2;
    }

    if (newIndex != _currentImageIndex) {
      setState(() {
        _currentImageIndex = newIndex;
      });
      // 触发切换时的缩小回弹动画
      _triggerSwitchAnimation();
    }
  }

  // 切换图片时的缩放动画:先缩小到0.7,再恢复到对应年龄的比例
  void _triggerSwitchAnimation() {
    final targetScale = _getScaleFromAge(_currentAge);
    _scaleController.reset();
    _scaleAnimation = TweenSequence([
      TweenSequenceItem(tween: Tween<double>(begin: targetScale, end: 0.7), weight: 1),
      TweenSequenceItem(tween: Tween<double>(begin: 0.7, end: targetScale), weight: 1),
    ]).animate(CurvedAnimation(parent: _scaleController, curve: Curves.easeInOut));
    _scaleController.forward();
  }

  // 根据年龄计算当前基础缩放比例
  double _getScaleFromAge(double age) {
    return minScale + (maxScale - minScale) * (age / 100);
  }

  @override
  Widget build(BuildContext context) {
    // 如果没有动画在执行,直接用计算的缩放比例;否则用动画值
    final currentScale = _scaleController.isAnimating ? _scaleAnimation.value : _getScaleFromAge(_currentAge);

    return Scaffold(
      appBar: AppBar(title: const Text('年龄选择')),
      body: Padding(
        padding: const EdgeInsets.all(20.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            // 可缩放切换的图片
            AnimatedBuilder(
              animation: _scaleAnimation,
              builder: (context, child) {
                return Transform.scale(
                  scale: currentScale,
                  child: child,
                );
              },
              child: _getCurrentImage(),
            ),
            const SizedBox(height: 40),
            // 年龄滑块
            Slider(
              value: _currentAge,
              min: 0,
              max: 100,
              divisions: 100,
              label: '${_currentAge.toInt()}岁',
              onChanged: (value) {
                setState(() {
                  _currentAge = value;
                });
                _updateImageIndex(value);
              },
            ),
            Text('当前年龄:${_currentAge.toInt()}岁', style: const TextStyle(fontSize: 18)),
          ],
        ),
      ),
    );
  }

  // 获取当前显示的图片
  Widget _getCurrentImage() {
    const imagePaths = [
      // 替换为你的孩童图片路径/AssetImage
      'assets/images/child.png',
      'assets/images/adult.png',
      'assets/images/elder.png',
    ];
    return Image.asset(
      imagePaths[_currentImageIndex],
      width: 200,
      height: 200,
      fit: BoxFit.contain,
    );
  }
}

关键部分说明

  1. 状态管理:用_currentAge绑定滑块值,_currentImageIndex控制显示的图片,AnimationController处理切换时的缩放动画
  2. 图片切换逻辑:_updateImageIndex方法根据年龄阈值(12岁以下孩童,60岁以上老人)切换图片索引,触发_triggerSwitchAnimation执行回弹效果
  3. 缩放计算:_getScaleFromAge将年龄(0-100)映射到0.8-1.2的缩放比例,实现随年龄增大图片放大的效果
  4. 动画处理:通过AnimatedBuilder监听缩放动画,Transform.scale应用缩放效果;切换图片时先缩小到0.7再恢复目标比例,增强切换感知

注意事项

  • 替换代码中的imagePaths为你实际的图片资源路径
  • 可根据需求调整minScale、maxScale、年龄阈值以及动画时长,适配不同的交互效果
  • 如果使用网络图片,将Image.asset替换为Image.network即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 18:32:52