Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter multiline with max lines

Tags:

flutter

I am using a textfield with these properties:

 TextField(
    controller: textController,    
    keyboardType: TextInputType.multiline,
    maxLines: 4,
    maxLength: 150,
 ),

Which works fine but I was wondering how I could prevent users from typing in break lines that would cause the text field to have more lines that the maxLines (4)..

Is there a way of locking the lines at 4? e.g.

input 1 \n \n \n should work

but 1 \n \n \n \n \n \n should not be allowed

like image 458
ebg11 Avatar asked Mar 19 '26 06:03

ebg11


2 Answers

I modified LengthLimitingTextInputFormatter to get my own MaxLinesTextInputFormatter.

Here is the code

class MaxLinesTextInputFormatter extends TextInputFormatter {
  MaxLinesTextInputFormatter(this.maxLines)
      : assert(maxLines == null || maxLines == -1 || maxLines > 0);

  final int maxLines;

  @override
  TextEditingValue formatEditUpdate(
    TextEditingValue oldValue, // unused.
    TextEditingValue newValue,
  ) {
    if (maxLines != null && maxLines > 0) {
      final regEx = RegExp("^.*((\n?.*){0,${maxLines - 1}})");
      String newString = regEx.stringMatch(newValue.text) ?? "";

      final maxLength = newString.length;
      if (newValue.text.runes.length > maxLength) {
        final TextSelection newSelection = newValue.selection.copyWith(
          baseOffset: math.min(newValue.selection.start, maxLength),
          extentOffset: math.min(newValue.selection.end, maxLength),
        );
        final RuneIterator iterator = RuneIterator(newValue.text);
        if (iterator.moveNext())
          for (int count = 0; count < maxLength; ++count)
            if (!iterator.moveNext()) break;
        final String truncated = newValue.text.substring(0, iterator.rawIndex);
        return TextEditingValue(
          text: truncated,
          selection: newSelection,
          composing: TextRange.empty,
        );
      }
      return newValue;
    }
    return newValue;
  }
}

Usage:

TextField(
  decoration: InputDecoration(),
  maxLines: 4,
  inputFormatters: [MaxLinesTextInputFormatter(4)],
)
like image 110
Crazy Lazy Cat Avatar answered Mar 21 '26 19:03

Crazy Lazy Cat


You can use allMatches() function to count the number of lines the input contains and update an error variable if the function returns 4 or more.

if (('\n'.allMatches(text).length + 1) > 4) { // check for new lines and update bool variable }

An example:

import 'package:flutter/material.dart';

class Demo extends StatefulWidget {
  @override
  _DemoState createState() => _DemoState();
}

class _DemoState extends State<Demo> {
  final textController = TextEditingController();

  bool error = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("DEMO"),
        ),
        body: Container(
            child: Column(children: [
          TextField(
            controller: textController,
            keyboardType: TextInputType.multiline,
            maxLines: 4,
            maxLength: 150,
            onChanged: (text) {
              setState(() {
                if (('\n'.allMatches(text).length + 1) > 4) {
                  error = true;
                } else {
                  error = false;
                }
              });
            },
          ),
          error ? Text("More than 4 lines entered") : Container()
        ])));
  }
}
like image 41
OMi Shah Avatar answered Mar 21 '26 20:03

OMi Shah



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!