Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to animate expandable Flutter widget to slide it out of the screen

I have two expandable buttons in a row occupied all screen width. On left button click I want left button to occupy whole screen width and right button to disappear by siding right, out of the screen. Here is what I achieved so far:

enter image description here

As you noticed, the right button gets squashed at the end when there is no enough space to render it. I just want it to continue moving out of the screen without changing it's width. I could achieve this by setting text one line for button, but I want the solution to work in general for all widgets (to look like there is the space to the right enough to render it).

Current solution:

import 'package:flutter/material.dart';

void main() => runApp(TestAnimation());

class TestAnimation extends StatefulWidget {
  @override
  _TestAnimationState createState() => _TestAnimationState();
}

class _TestAnimationState extends State<TestAnimation> with SingleTickerProviderStateMixin {
  AnimationController _animationController;
  Animation _animation;

  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(duration: Duration(seconds: 2), vsync: this);
    _animation = IntTween(begin: 100, end: 0).animate(_animationController);
    _animation.addListener(() => setState(() {}));
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Row(
            children: <Widget>[
              Expanded(
                flex: 100,
                child: OutlineButton(
                  child: Text("Left"),
                  onPressed: () {
                    if (_animationController.value == 0.0) {
                      _animationController.forward();
                    } else {
                      _animationController.reverse();
                    }
                  },
                ),
              ),
              Expanded(
                flex: _animation.value,
                // Uses to hide widget when flex is going to 0
                child: SizedBox(
                  width: 0,
                  child: OutlineButton(
                    child: Text(
                      "Right",
                    ),
                    onPressed: () {},
                  ),
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}
like image 724
Oleksii Masnyi Avatar asked Feb 21 '19 15:02

Oleksii Masnyi


People also ask

How do I hide and show widgets with animation in Flutter?

Flutter provides AnimatedOpacity Widget to change the opacity of the widget when show and hide in progress. It will linearly change the opacity and you can change the curve (how the animation should happen) by setting values like bounceIn, easeInOut etc. The main property which you need to set is opacity.


1 Answers

UPDATE: Other way would to define TextOverflow for Text Widget.

Expanded(
                flex: _animation.value,
                // Uses to hide widget when flex is going to 0
                child: SizedBox(
                  width: 0.0,
                  child: OutlineButton(
                    child: Text(
                      "Right",
                      overflow: TextOverflow.ellipsis, // Add this
                    ),
                    onPressed: () {},
                  ),
                ),
              )

This ( right button gets squashed) can be solved with help of FittedBox widget.

import 'package:flutter/material.dart';

void main() => runApp(TestAnimation());

class TestAnimation extends StatefulWidget {
  @override
  _TestAnimationState createState() => _TestAnimationState();
}

class _TestAnimationState extends State<TestAnimation> with SingleTickerProviderStateMixin {
  AnimationController _animationController;
  Animation _animation;

  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(duration: Duration(seconds: 2), vsync: this);
    _animation = IntTween(begin: 100, end: 0).animate(_animationController);
    _animation.addListener(() => setState(() {}));
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Row(
            children: <Widget>[
              Expanded(
                flex: 100,
                child: OutlineButton(
                  child: Text("Left"),
                  onPressed: () {
                    if (_animationController.value == 0.0) {
                      _animationController.forward();
                    } else {
                      _animationController.reverse();
                    }
                  },
                ),
              ),
              Expanded(
                flex: _animation.value,
                // Uses to hide widget when flex is going to 0
                child: SizedBox(
                  width: 0.0,
                  child: OutlineButton(
                    child: FittedBox(    //Add this
                      child: Text(
                        "Right",
                      ),
                    ),
                    onPressed: () {},
                  ),
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}

output:

enter image description here

like image 70
anmol.majhail Avatar answered Nov 15 '22 06:11

anmol.majhail