AnimatedContainer 由于高度问题无法将 TextField 动画化为全屏

问题描述 投票:0回答:1

我需要创建一个具有特定行为的文本字段,例如松弛文本字段:

  1. 向上滑动时,文本字段应动画为全屏,向下滑动时应最小化。

  2. 当处于最小化状态时,TextField 应根据内容动态调整其高度,最多 5 行。达到 5 行后,它应该启用滚动。

我使用 AnimatedContainer 来处理动画。当我有条件地设置高度时,就会出现问题,动画停止工作:

height: isFullScreen ? textFieldHeight : null,

但是,如果我设置像

height: textFieldHeight
这样的固定高度或在条件下给出默认高度,动画将按预期工作。缺点是 TextField 在最小化状态下不会动态调整其高度。当我这样做时,文本字段保持其初始状态,并且不会通过添加新行来增长
height: textFieldHeight
.

这是我的函数代码:

  KeyboardVisibilityBuilder _getTextFieldContainer(BuildContext context) {
    return KeyboardVisibilityBuilder(
      builder: (context, isKeyboardVisible) {
        return Stack(
            children: [ SingleChildScrollView(
              child: Container(
                  width: double.infinity,
                  decoration: BoxDecoration(
                    border:
                    Border.all(color: Get.isDarkMode ? darkGrey : lightGrey),
                    color: widget.backgroundColor,
                    borderRadius: const BorderRadius.only(
                        topLeft: Radius.circular(8), topRight: Radius.circular(8)),
                  ),
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      Padding(
                          padding: const EdgeInsets.only(left: 12, right: 12),
                          child: GestureDetector(
                              onVerticalDragUpdate: (details) {
                                if (details.delta.dy > 0) { // Swipe down
                                  if (isFullScreen) {
                                    toggleFullScreen(context);
                                  }
                                }
                                else if (details.delta.dy < 0) { // Swipe up
                                  if (!isFullScreen) {
                                    toggleFullScreen(context);
                                  }
                                }
                                },
                              child: AnimatedContainer(
                                  duration: Duration(milliseconds: 500),
                                  curve: Curves.easeInOut,
                                  height: isFullScreen ? textFieldHeight : bottomBarHeight,
                                  child: TextField(
                                    focusNode: _textFieldFocusNode,
                                    controller: _chatController.textEditingController.value,
                                    minLines: 1,
                                    maxLines: isFullScreen ? null : (isKeyboardVisible ? 5 : 1),
                                    keyboardType: TextInputType.multiline,
                                    textInputAction: TextInputAction.newline,
                                    autocorrect: false,
                                    cursorColor:
                                        Get.isDarkMode ? Colors.white : primaryColor,
                                    decoration: InputDecoration(
                                      enabledBorder: const UnderlineInputBorder(
                                        borderSide: BorderSide(color: Colors.transparent),
                                      ),
                                      focusedBorder: InputBorder.none,
                                      hintText: widget.submitType == SubmitType.view
                                          ? 'Have a question? Ask now!'
                                          : 'Type here',
                                      suffixIcon: isKeyboardVisible || isFullScreen
                                          ? null
                                          : Row(
                                        mainAxisSize: MainAxisSize.min,
                                        children: [
                                          Obx(() => _getSpeechToText()),
                                          Obx(() => _getTextFieldSuffix()),
                                        ],
                                      ),
                                    ),
      
                        onChanged: (value) {
                          setState(
                            () {},
                          );
                        },
                      ))
                    )),
                  isKeyboardVisible
                      ? _textFieldBottomBar(context)
                      : const SizedBox.shrink(),
                ],
              )),
        ) ,
              if (isKeyboardVisible || isFullScreen)
                Positioned(
                bottom: 0,
                left: 0,
                right: 0,
                child: _textFieldBottomBar(context),
              )]);
      },
    );
  }
     @override
  Widget build(BuildContext context) {
    return _getTextFieldContainer(context);
  }

这是用于向上滑动和向下滑动以及设置全屏的textFieldHeight:

  double textFieldHeight = 50.0;
  double bottomBarHeight = 50.0;
  bool isFullScreen = false;

  void toggleFullScreen(BuildContext context) {
    setState(() {
      isFullScreen = !isFullScreen;
      double screenHeight = MediaQuery.of(context).size.height;
      textFieldHeight = isFullScreen ? screenHeight - bottomBarHeight : 50.0;
    });
  }

如何实现最小化状态下的上下滑动动画和动态高度调整?具体如何实现动画效果?

flutter flutter-animation swipe-gesture
1个回答
0
投票

不管怎样,我现在已经解决了

当 isFullScreen 为 false 时,我将 AnimatedContainer 的高度设置为 null。我将 BoxConstraints 添加到 AnimatedContainer 以在 isFullScreen 为 false 时设置最小和最大高度。这允许 TextField 动态增长最多 5 行。我用 IntrinsicHeight 小部件包装了 TextField,以确保它具有所需的最小高度。 这将允许您在最小化状态下同时具有向上滑动/向下滑动动画和动态高度调整。

child: AnimatedContainer(
                        duration: Duration(milliseconds: 500),
                        curve: Curves.easeInOut,
                        height: isFullScreen
                            ? textFieldHeight
                            : null,
                        constraints: isFullScreen
                            ? null
                            : BoxConstraints(
                                minHeight: bottomBarHeight,
                                maxHeight: 5 * bottomBarHeight), 
                        child: IntrinsicHeight(
                          child: TextField(
© www.soinside.com 2019 - 2024. All rights reserved.