这个动画是如何实现的?

How this animation can be implemented?

这个动画的最佳方法是什么? Row + Flexible + AnimatedSize + Image ? 或 Rive。提前谢谢你。

您可以在选择一张卡时使用动画容器进行此操作,然后将减少另一张卡height/width,并且会增加所选容器height/width。

Flutter Cookbook - Animate the properties of a container

辛辛苦苦做出来的,一定能帮到你

导入 'dart:math'; 导入 'package:flutter/cupertino.dart'; 导入 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    home: Animation(),
  ));
}

class Animation extends StatefulWidget {
  @override
  _AnimationState createState() => _AnimationState();
}

class _AnimationState extends State<Animation> {
  Map<String, String> map1 = {"0": 'zero', "1": "One", "2": "Two"};
  int selectedIndex = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Container(
          color: Colors.white,
          padding: EdgeInsets.only(left: 6),
          child: Animated(
              items: map1,
              animationDuration: const Duration(milliseconds: 400),
              onTap: (index) {
                setState(() {
                  selectedIndex = index;
                });
              }),
        ),
      ),
    );
  }
}

class Animated extends StatefulWidget {
  var items;
  final Duration animationDuration;
  final Function onTap;

  Animated(
      {this.items,
      this.animationDuration = const Duration(milliseconds: 300),
      required this.onTap});

  @override
  _AnimatedState createState() => _AnimatedState();
}

class _AnimatedState extends State<Animated>
    with TickerProviderStateMixin {
  int selectedIndex = 0;
  late double height = 100, width = 100;

  @override
  Widget build(BuildContext context) {
    /* height = MediaQuery.of(context).size.height;
    width = MediaQuery.of(context).size.width;*/
    return Container(
      height: 100,
      width: double.infinity,
      padding: EdgeInsets.only(top: 2, bottom: 2),
      child: ListView(
        scrollDirection: Axis.horizontal,
        children: _buildItems(),
      ),
    );
  }

  List<Widget> _buildItems() {
    List<Widget> _Items = [];
    for (int i = 0; i < widget.items.length; i++) {
      bool isSelected = selectedIndex == i;
      _Items.add(
        InkWell(
          splashColor: Colors.transparent,
          onTap: () {
            setState(() {
              selectedIndex = i;
              widget.onTap(selectedIndex);
            });
          },
          child: AnimatedContainer(
            width: isSelected == true ? width + 60 : width,
            margin: EdgeInsets.only(left: 2, right: 2),
            padding:
                const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
            duration: widget.animationDuration,
            decoration: BoxDecoration(
              borderRadius: BorderRadius.all(Radius.circular(2.0)),
              gradient: LinearGradient(
                colors: [
                  Colors.blue,
                  Colors.primaries[Random().nextInt(Colors.primaries.length)]
                ],
              ),
            ),
            child: Text(widget.items[i.toString()]),
          ),
        ),
      );
    }
    return _Items;
  }
}