skip to Main Content

In my Flutter Chat App I am trying to design a chat TextField.

image of the design

I want to increase the height of the TextField dynamically when text input goes to new line either from an enter butoon or text overflow from the same line.

I tried different maxLine, minLine combinations, used Expanded in different parent widget level.
Here is my code snippet:

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

  @override
  State<ChatScreen> createState() => _ChatScreenState();
}

class _ChatScreenState extends State<ChatScreen> {
  late TextEditingController _chatTextController;
  late bool _isEnabled;
  late FocusNode _chatTextFocusNode;
  late double _textFieldHeight;
  ScrollController textFieldScrollController = ScrollController();

  @override
  void initState() {
    super.initState();
    _chatTextController = TextEditingController();
    _isEnabled = true;
    _chatTextFocusNode = FocusNode();
    _textFieldHeight = 88.h;
  }

  @override
  void dispose() {
    _chatTextController.dispose();
    _chatTextFocusNode.dispose();
    _isEnabled = false;
    textFieldScrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
      child: SafeArea(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Row(
              children: [
                Gap(4.w),
                const CustomBackButton(
                  previousScreen: 'welcome',
                  assetIcon: 'assets/icons/home.png',
                ),
                Gap(4.w),
                Text(
                  'Chat Screen',
                  style: TextStyle(
                    fontSize: 22.sp,
                    fontWeight: FontWeight.w400,
                    color: AppColors.titleTextBlack,
                  ),
                ),
              ],
            ),
            SizedBox(
              height: _textFieldHeight,
              child: Column(
                children: [
                  Divider(
                    height: 0,
                    thickness: 1.h,
                    color: const Color(0xFFBEC9C7),
                  ),
                  Padding(
                    padding:
                        EdgeInsets.symmetric(vertical: 16.h, horizontal: 24.w),
                    child: Row(
                      children: [
                        _chatBox(),
                        Gap(8.w),
                        ChatBoxIconButton(
                          onPressed: () {
                            print('*********');
                          },
                          icon: Icons.send_rounded,
                          backgroundColor: AppColors.mainGreen,
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _chatBox() {
    return Container(
      height: 56.h,
      width: 308.w,
      padding: EdgeInsets.only(left: 16.w, top: 4.h, bottom: 4.h),
      decoration: BoxDecoration(
        border: Border.all(color: AppColors.regularTextGrey),
        borderRadius: BorderRadius.circular(100.r),
      ),
      child: Row(
        children: [
          Expanded(
            //width: 242.w,
            child: TextField(
              // expands: true,
              cursorHeight: 18.sp,
              cursorColor: AppColors.mainGreen,
              controller: _chatTextController,
              scrollController: textFieldScrollController,
              focusNode: _chatTextFocusNode,
              keyboardType: TextInputType.multiline,
              onChanged: (value) {
                textFieldScrollController
                    .jumpTo(textFieldScrollController.position.maxScrollExtent);
              },
              // maxLines: 3,
              minLines: 3,
              maxLines: null,
              //minLines: null,
              style:
                  TextStyle(fontSize: 16.sp, color: AppColors.regularTextBlack),
              decoration: InputDecoration(
                hintText: 'Ask me anything',
                hintStyle: TextStyle(
                    fontSize: 16.sp, color: AppColors.regularTextGrey),
                border: InputBorder.none,
              ),
            ),
          ),
          ChatBoxIconButton(
            onPressed: () {
              print('*********');
            },
            icon: CupertinoIcons.mic,
            backgroundColor: Colors.white,
            iconColor: AppColors.regularTextGrey,
          ),
        ],
      ),
    );
  }
}

I would really appreciate your kind help. Thank you all.

2

Answers


  1. Try below code and set maxline:null refer maxLines

    TextFormField(
          maxLines: null,
          decoration: InputDecoration(
            contentPadding: EdgeInsets.all(5),
            hintText: "Hint",
            labelText: "Enter Something",
            border: OutlineInputBorder(
              borderRadius: BorderRadius.circular(10.0),
            ),
          ),
        ),
    

    Result: enter image description here

    Login or Signup to reply.
  2. As mentioned by @ravindra-s-patil, you can use maxLines: null to make a TextField auto resize. Although the documentation says it will grow "up to the height of its constraints", the height of the input field can easily overflow in practice:

    TextField Height Overflow

    So, instead of maxLines: null, you may need both maxLines and minLines, like this:

    TextField(
      minLines: 1,
      maxLines: 12,
      // ...
    )
    

    Here maxLines is set to a number (greater than 1) to limit the maximum number of lines, and minLines is used to specify the initial number of lines.

    In this case, the input field will start out with 1 line, and as you enter more text, it will automatically expand up to 12 lines. If the text exceeds the line limit, you can still scroll the text within the box.

    As a nice Flutter chat app example, Flyer uses the same technique as we described above.

    If you prefer to see it in action, check out my video explanation.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search