简体   繁体   English

Flutter:在无状态小部件中动画行内容

[英]Flutter: Animating Row contents within a stateless widget

I have a Row that is made out of either one or two elements.我有一个由一个或两个元素组成的行。 Depending on the latter, I want to animate the width of the first element to either be fully expanded, or to accommodate for the second element.根据后者,我想为第一个元素的宽度设置动画,使其要么完全展开,要么适应第二个元素。

I am using AnimatedContainers within the row to achieve this, but there is no animation.我在行内使用 AnimatedContainers 来实现这一点,但没有 animation。 I thought this probably has to do with Flutter not recognizing it as the same after re-rendering based on its parent's state, so I tried using a Unique Key.我认为这可能与 Flutter 在基于其父级的 state 重新渲染后没有将其识别为相同有关,所以我尝试使用唯一密钥。 This however didn't work either.然而,这也不起作用。

class TabsBar extends StatelessWidget {
  TabsBar({this.currentIndex, this.onIndexChanged, Key key}) : super(key: key);
  final int currentIndex;
  final Function(int) onIndexChanged;

  @override
  Widget build(BuildContext context) {
    final tabsBloc = BlocProvider.of<TabsBarBloc>(context);

  return BlocBuilder<TabsBarBloc, TabsBarBlocState>(
    builder: (context, tabsBarState) {
  return SafeArea(
    child: Padding(
      padding: const EdgeInsets.symmetric(horizontal: standardSpacing),
      child: Row(
        children: [
          Expanded(
            child: AnimatedContainer(
              key: key,
              height: 60,
              duration: Duration(milliseconds: 200),
              //....//
          ),
          //HERE: IF INDEX IS == 2, I WANT THE CONTAINER ABOVE TO ANIMATE INTO ITS NEW SIZE WHICH IS LESS WIDE TO ACCOMMODATE FOR THE CONTAINER BELOW
          currentIndex == 2
              ? GestureDetector(
                  onTap: () {},
                  behavior: HitTestBehavior.translucent,
                  child: AnimatedContainer(
                    duration: Duration(milliseconds: 200),
                    padding: const EdgeInsets.only(left: standardSpacing),
                    height: 60,
                    child: Image.asset(
                      '${imagesPath}add_piece.png',
                    ),
                  ),
                )
              : HorizontalSpacing(0),
        ],
      ),
    ),
  );
});

I also tried using a Layout Builder to define the width explicitly and using an Animated Container as a parent to the Row.我还尝试使用 Layout Builder 显式定义宽度,并使用 Animated Container 作为 Row 的父级。 Neither worked.都没有奏效。

Can anybody point me towards what I might be missing?任何人都可以指出我可能会错过什么吗?

I don't fully understand what value of the AnimatedContainer are you trying to change but it could be easier to just animate the second container of the row and change it's width to 0 so it dissapears from the screen我不完全理解 AnimatedContainer 的值是什么你试图改变,但它可能更容易只为该行的第二个容器设置动画并将其宽度更改为 0,以便它从屏幕上消失

class Home extends StatefulWidget {
  @override
  State<Home> createState() => HomeState();
}

class HomeState extends State<Home> {
  int currentIndex = 2; //or you could use a boolean type

  @override
  Widget build(BuildContext context) {
    return Column(mainAxisSize: MainAxisSize.min, children: [
      MyWidget(
        currentIndex: currentIndex,
      ),
      FlatButton(
          onPressed: () => setState(() {
                currentIndex = currentIndex == 1 ? 2 : 1;
              }),
          child: Text('Change'))
    ]);
  }
}

class MyWidget extends StatelessWidget {
  final int currentIndex;
  static const double standardSpacing = 8.0;

  MyWidget({this.currentIndex, Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: standardSpacing),
        child: Row(
          children: [
            Expanded(
             child: Container( //Normal Container
               height: 60,
               color: Colors.blue)
            ),
            GestureDetector(
              onTap: () {},
              behavior: HitTestBehavior.translucent,
              child: AnimatedContainer(
                duration: Duration(milliseconds: 200),
                padding: const EdgeInsets.only(left: standardSpacing),
                height: 60,
                width: currentIndex == 2 ? 36 : 0, //when currentIndex is not 2, it's size its zero
                child: const Icon(Icons.save),
              ),
            )
          ],
        ),
      ),
    );
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM