In my Flutter Chat App I am trying to design a chat TextField
.
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
Try below code and set
maxline:null
refer maxLinesResult:
As mentioned by @ravindra-s-patil, you can use
maxLines: null
to make aTextField
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:So, instead of
maxLines: null
, you may need bothmaxLines
andminLines
, like this:Here
maxLines
is set to a number (greater than 1) to limit the maximum number of lines, andminLines
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.