How this animation can be implemented?

376 Views Asked by At

What is the best approach for this animation? Row + Flexible + AnimatedSize + Image ? or Rive. Thank you in advance.

enter image description here

3

There are 3 best solutions below

0
On BEST ANSWER

You can do this using an animated container when one card is selected then another card's height/width will be decreased and the selected container height/width will be increased.

Flutter Cookbook - Animate the properties of a container

1
On

Try this if you want to animate the container

import 'dart:math';

import 'package:flutter/material.dart';

void main() => runApp(const AnimatedContainerApp());

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

  @override
  State<AnimatedContainerApp> createState() => _AnimatedContainerAppState();
}

class _AnimatedContainerAppState extends State<AnimatedContainerApp> {
  // Define the various properties with default values. Update these properties
  // when the user taps a FloatingActionButton.
  double _width = 50;
  double _height = 50;
  Color _color = Colors.green;
  BorderRadiusGeometry _borderRadius = BorderRadius.circular(8);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('AnimatedContainer Demo'),
        ),
        body: Center(
          child: AnimatedContainer(
            // Use the properties stored in the State class.
            width: _width,
            height: _height,
            decoration: BoxDecoration(
              color: _color,
              borderRadius: _borderRadius,
            ),
            // Define how long the animation should take.
            duration: const Duration(seconds: 1),
            // Provide an optional curve to make the animation feel smoother.
            curve: Curves.fastOutSlowIn,
          ),
        ),
        floatingActionButton: FloatingActionButton(
          // When the user taps the button
          onPressed: () {
            // Use setState to rebuild the widget with new values.
            setState(() {
              // Create a random number generator.
              final random = Random();

              // Generate a random width and height.
              _width = random.nextInt(300).toDouble();
              _height = random.nextInt(300).toDouble();

              // Generate a random color.
              _color = Color.fromRGBO(
                random.nextInt(256),
                random.nextInt(256),
                random.nextInt(256),
                1,
              );

              // Generate a random border radius.
              _borderRadius =
                  BorderRadius.circular(random.nextInt(100).toDouble());
            });
          },
          child: const Icon(Icons.play_arrow),
        ),
      ),
    );
  }
}

enter image description here

0
On

I just worked hard to make like this, this will surely help you

enter image description here

import 'dart:math';
import 'package:flutter/cupertino.dart';
import '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;
  }
}