首页 > 解决方案 > 在 Flutter 中通过动画缓慢显示小部件

问题描述

我有一个小部件,单击它会显示另一个小部件,第二次它会关闭。我需要添加一些动画,以便我可以看到打开或关闭。现在它只是非常快速/立即打开和关闭。

我的代码:

          Padding(
            padding: const EdgeInsets.only(left: 13, right: 13, top: 13),
            child: Container(
              decoration: BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.all(Radius.circular(10)),
                boxShadow: [
                  BoxShadow(
                    color: Colors.grey.withOpacity(0.1),
                    spreadRadius: 2,
                    blurRadius: 3,
                    offset: Offset(0, 3), // changes position of shadow
                  ),
                ],
              ),
              child: Padding(
                padding: const EdgeInsets.all(8.0),
                child: Container(
                  child: Center(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.center,
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Padding(
                          padding: const EdgeInsets.only(left: 8, right: 8),
                          child: Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            crossAxisAlignment: CrossAxisAlignment.center,
                            children: [
                              Text(
                                'DIAGNOSIS',
                                style: TextStyle(
                                    color: kPrimaryColor,
                                    fontFamily: 'PoppinsMedium',
                                    fontSize: 14),
                              ),
                              showB
                                  ? GestureDetector(
                                  onTap: () {
                                    print('false');
                                    setState(() {
                                      showB = false;
                                    });
                                  },
                                  child: Icon(
                                      Icons.keyboard_arrow_up_outlined))
                                  : GestureDetector(
                                  onTap: () {
                                    print('true');
                                    setState(() {
                                      showB = true;
                                    });
                                  },
                                  child: Icon(
                                      Icons.keyboard_arrow_down_outlined))
                            ],
                          ),
                        ),
                        showB
                            ? Column(
                          children: [
                            Padding(
                              padding: const EdgeInsets.only(top: 8),
                              child: Container(
                                width: Width * 0.9,
                                child: Divider(
                                  color: Colors.grey,
                                ),
                              ),
                            ),
                            Padding(
                              padding: const EdgeInsets.only(
                                  left: 8, right: 8, bottom: 8, top: 2),
                              child: Container(
                                child: Column(
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  children: [


                                    Padding(
                                      padding: const EdgeInsets.only(top: 10, left: 7, bottom: 5),
                                      child: Text('Diagnosis',
                                          textAlign: TextAlign.left,
                                          style: TextStyle(fontFamily: 'PoppinsRegular', color: kPrimaryColor,)),
                                    ),
                                    Container(
                                      width: Width * 0.92 ,
                                      child: TextFormField(
                                        onChanged: (value) {

                                        },
                                        onSaved: (value) {},
                                        style: TextStyle(
                                            fontSize: 15,
                                            color: kPrimaryColor,
                                            fontFamily: 'UbuntuRegular'),
                                        decoration: new InputDecoration(
                                          suffixIcon: IconButton(
                                            icon: Icon(
                                              Icons.search_outlined,
                                              color: Color(0xffbdbdbd),
                                            ),
                                          ),
                                          border: new OutlineInputBorder(
                                            borderSide:
                                            const BorderSide(color: Color(0xffbdbdbd), width: 1),
                                            borderRadius: const BorderRadius.all(
                                              const Radius.circular(10.0),
                                            ),
                                          ),
                                          enabledBorder: new OutlineInputBorder(
                                            borderSide:
                                            const BorderSide(color: Color(0xffbdbdbd), width: 1),
                                            borderRadius: const BorderRadius.all(
                                              const Radius.circular(10.0),
                                            ),
                                          ),
                                          filled: true,
                                          hintStyle: new TextStyle(
                                              color: Color(0xffbdbdbd), fontFamily: 'UbuntuRegular'),
                                          hintText: "Enter Diagnosis",
                                          fillColor: Colors.white70,
                                          focusedBorder: OutlineInputBorder(
                                            borderSide: const BorderSide(color: kPrimaryColor, width: 1),
                                            borderRadius: const BorderRadius.all(
                                              const Radius.circular(10.0),
                                            ),
                                          ),
                                        ),
                                      ),
                                    ),
                                    Padding(
                                      padding: const EdgeInsets.only(top: 10, left: 7, bottom: 5),
                                      child: Text('Comments',
                                          textAlign: TextAlign.left,

                                          style: TextStyle(fontFamily: 'PoppinsRegular', color: kPrimaryColor,)),
                                    ),
                                    Container(
                                      width: Width * 0.92 ,
                                      child: TextFormField(
                                        maxLines: 5,// when user presses enter it will adapt to it
                                        onChanged: (value) {

                                        },
                                        onSaved: (value) {},
                                        style: TextStyle(
                                            fontSize: 15,
                                            color: kPrimaryColor,
                                            fontFamily: 'UbuntuRegular'),
                                        decoration: new InputDecoration(
                                          border: new OutlineInputBorder(
                                            borderSide:
                                            const BorderSide(color: Color(0xffbdbdbd), width: 1),
                                            borderRadius: const BorderRadius.all(
                                              const Radius.circular(10.0),
                                            ),
                                          ),
                                          enabledBorder: new OutlineInputBorder(
                                            borderSide:
                                            const BorderSide(color: Color(0xffbdbdbd), width: 1),
                                            borderRadius: const BorderRadius.all(
                                              const Radius.circular(10.0),
                                            ),
                                          ),
                                          filled: true,
                                          hintStyle: new TextStyle(
                                              color: Color(0xffbdbdbd), fontFamily: 'UbuntuRegular'),
                                          hintText: "Enter Comments",
                                          fillColor: Colors.white70,
                                          focusedBorder: OutlineInputBorder(
                                            borderSide: const BorderSide(color: kPrimaryColor, width: 1),
                                            borderRadius: const BorderRadius.all(
                                              const Radius.circular(10.0),
                                            ),
                                          ),
                                        ),
                                      ),
                                    ),
                                    Align(
                                        alignment: Alignment.centerRight ,
                                        child: Padding(
                                          padding: const EdgeInsets.only(top: 13),
                                          child: Container(
                                                  decoration: BoxDecoration(
                                                    color: kPrimaryColor,
                                                shape: BoxShape.circle,
                                              ),
                                              child: Padding(
                                                padding: const EdgeInsets.all(4.0),
                                                child: Icon(
                                                Icons.add,
                                                size: 25.0,
                                                color:Colors.white
                                          ),
                                              )
                                          ),
                                        )
                                    ),
                                    Align(
                                      alignment: Alignment.center,
                                      child: Padding(
                                        padding: const EdgeInsets.only(top: 15, left: 7, bottom: 5),
                                        child: RawMaterialButton(
                                          onPressed: () {
                                            print('sad');
                                            setState(() {
                                              showA = false;
                                              showB = false;
                                              showC = true;
                                              showD = false;
                                            });
                                          },
                                          elevation: 2.0,
                                          fillColor: Colors.white,
                                          child: Icon(
                                              Icons.check_outlined,
                                              size: 35.0,
                                              color:kPrimaryColor
                                          ),
                                          padding: EdgeInsets.all(15.0),
                                          shape: CircleBorder(),
                                        ),
                                      ),
                                    )


                                  ],
                                ),
                              ),
                            )
                          ],
                        )
                            : Container()
                      ],
                    ),
                  ),
                ),
              ),
            ),
          ),

我只想让容器像轻弹一样打开或关闭。那么如何添加动画以使其关闭或打开速度稍慢或带有一些动画?

标签: flutterdart

解决方案


这更像是一个基于意见的问题。但一种简单的方法是Implicit Animations在 Flutter 中使用。

对于您的情况,您可以使用AnimatedSize.

首先,添加with TickerProviderStateMixin到您的State<T>类定义中。比如像这样,

class MyAppState extends State<MyApp> with TickerProviderStateMixin {

然后,你有一个列的第二个孩子是Column这样的

showB ? Column( ..... ) : Container()

删除条件和其他情况Container并将其更改为此,

Column( ..... )

现在,将它包裹Column在一个AnimatedSize和这样的Container小部件中,

AnimatedSize(
  vsync: this,
  duration: Duration(milliseconds: 250),
  child: Container(
    height: showB ? null : 0,
    child: Column( ..... ), // This is the same widget from above
  )
)

现在,您的元素应该会自动生成动画。

此代码可能难以理解,因此请查看此pastebin以获取完整代码。

请注意,我已经删除了kPrimaryColorandWidth变量,因为您没有在代码中提供它们。

检查此 gif 以了解它是如何工作的。

在此处输入图像描述

现在,这是一个非常简单的动画,你绝对可以让它变得更好。阅读更多关于Flutter 中的隐式动画


推荐阅读