Trzepocze wielowierszowe pole tekstowe

130

To może wydawać się łatwe, ale jak możemy zrobić wieloliniowe edytowalne pole tekstowe w trzepotaniu? TextField działa tylko z jedną linią.

Edycja: pewne szczegóły, ponieważ wydaje się, że nie jest jasne. Chociaż możesz ustawić multilinię na wirtualne zawijanie treści tekstowej, nadal nie jest to multilinia. Jest to pojedyncza linia wyświetlana w wielu wierszach. Jeśli chcesz zrobić coś takiego, nie możesz. Ponieważ nie masz dostępu do ENTERprzycisku. Brak przycisku Enter oznacza brak multilinii.

Rémi Rousselet
źródło

Odpowiedzi:

223

Aby użyć automatycznego zawijania, ustaw maxLinesjako null:

TextField(
  keyboardType: TextInputType.multiline,
  maxLines: null,
)

Jeśli maxLineswłaściwość ma wartość null, nie ma ograniczenia liczby wierszy, a zawijanie jest włączone.

Fellipe Sanches
źródło
Jest haczyk maxLines: null. Bez hi to nie działa
Sisir
Jeśli chcesz, aby wyglądało to grubiej jak <textarea>w HTML, użyjminLines: 4
Nabeel Parkar
30

Jeśli chcesz, aby Twoje TextField dostosowywało się do danych wprowadzanych przez użytkownika, zrób to:

TextField(
    keyboardType: TextInputType.multiline,
    minLines: 1,//Normal textInputField will be displayed
    maxLines: 5,// when user presses enter it will adapt to it
    );

tutaj ustaw maksymalne linie na cokolwiek chcesz i jesteś gotowy. Moim zdaniem ustawienie maxlines na null nie jest dobrym wyborem, powinniśmy nadać mu jakąś wartość.

taranjeet singh
źródło
1
Poprawiłem nazwę widżetu z: TextInputField, na: TextField. We flutter nie ma TextInputField, tylko TextField lub TextFormField. Chyba że utworzysz taki z własną nazwą.
Cassio Seffrin
15

Chociaż inne osoby wspomniały już, że można użyć klawiatury typu „TextInputType.multiline”, chciałem dodać moją implementację TextField, która automatycznie dostosowuje swoją wysokość po wprowadzeniu nowej linii, ponieważ często jest pożądane, aby imitować zachowanie wejściowe WhatsApp i podobne aplikacje.

Analizuję liczbę znaków „\ n” na wejściu w tym celu za każdym razem, gdy tekst jest zmieniany. Wydaje się, że jest to przesada, ale niestety nie znalazłem do tej pory lepszej możliwości osiągnięcia tego beahivour we Flutterze i nie zauważyłem żadnych problemów z wydajnością nawet na starszych smartfonach.

class _MyScreenState extends State<MyScreen> {
  double _inputHeight = 50;
  final TextEditingController _textEditingController = TextEditingController();

  @override
  void initState() {
    super.initState();
    _textEditingController.addListener(_checkInputHeight);
  }

  @override
  void dispose() {
    _textEditingController.dispose();
    super.dispose();
  }

  void _checkInputHeight() async {
    int count = _textEditingController.text.split('\n').length;

    if (count == 0 && _inputHeight == 50.0) {
      return;
    }
    if (count <= 5) {  // use a maximum height of 6 rows 
    // height values can be adapted based on the font size
      var newHeight = count == 0 ? 50.0 : 28.0 + (count * 18.0);
      setState(() {
        _inputHeight = newHeight;
      });
    }
  }


  // ... build method here
  TextField(
    controller: _textEditingController,
    textInputAction: TextInputAction.newline,
    keyboardType: TextInputType.multiline,
    maxLines: null,
  )
Jeff S.
źródło
1
Zastanów się nad dodaniem, jak faktycznie używasz _inputHeight, aby ustawić wysokość wejścia
Ali Nasserzadeh,
Ponieważ TextField może zawijać linię bez dzielenia linii za pomocą „\ n”, liczba nie powiedzie się. Więc liczę wiersze tekstu za pomocą tego kodu: int count = (_textEditingController.text.length / (MediaQuery.of (context) .size.width * 0.06)) .round ();
Reginaldo Rigo
6

Użyj tego

TextFormField(
      keyboardType: TextInputType.multiline,
      maxLines: //Number_of_lines(int),)
Muhannad Mahamooad
źródło
5

TextFieldma właściwość maxLines .

wprowadź opis obrazu tutaj

Niemiecki Saprykin
źródło
1
Wiem to. Chociaż zawija zawartość, nadal nie możesz nacisnąć klawisza Enter, aby ręcznie utworzyć nowy wiersz. Przynajmniej na Androidzie, ponieważ nie masz dostępu do przycisku Enter.
Rémi Rousselet
Ach, przegapiłem ten problem. Widziałem podobny problem z 2016 roku, więc założyłem, że został rozwiązany. Dość smutne, że nadal nie możemy tego zrobić.
Rémi Rousselet
2
Wygląda na to, że zostało to naprawione ( github.com/flutter/flutter/issues/8028 ). Wypróbowałem wiele linii na iOS i Androidzie i oba mogą teraz tworzyć nowe linie w polu tekstowym.
Matt S.
W rzeczywistości może teraz utworzyć nową linię, ale musi dwukrotnie nacisnąć klawisz Enter!
wendu,
5

Użyj expandsi nie musisz podawać minLinesani maxLinesżadnej konkretnej wartości:

TextField(
  maxLines: null,
  expands: true, 
  keyboardType: TextInputType.multiline,
)
CopsOnRoad
źródło
2
   TextFormField(
                  minLines: 2,
                  maxLines: 5,
                  keyboardType: TextInputType.multiline,
                  decoration: InputDecoration(
                    hintText: 'description',
                    hintStyle: TextStyle(
                      color: Colors.grey
                    ),
                    border: OutlineInputBorder(
                      borderRadius: BorderRadius.all(Radius.circular(20.0)),
                    ),
                  ),
                ),
Omar Alshyokh
źródło
1

jeśli powyższe raz nie zadziałało, spróbuj dodać również minLines

TextField(
        keyboardType: TextInputType.multiline,
        minLines: 3,
        maxLines: null);
Sai Gopi Me
źródło
1

Chociaż to pytanie jest dość stare, nie ma obszernej odpowiedzi, która wyjaśnia, jak dynamicznie zmieniać rozmiar TextFieldprzy niewielkim wysiłku programisty. Jest to szczególnie ważne, gdy TextFieldjest umieszczony w flexboksie, takim jak ListView, SingleChildScrollView itp. (Flexbox nie będzie w stanie określić wewnętrznego rozmiaru elementu rozszerzalnego TextField).

Zgodnie z sugestiami wielu innych użytkowników, zbuduj coś TextFieldtakiego:

TextField(
  textInputAction: TextInputAction.newline,
  keyboardType: TextInputType.multiline,
  minLines: null,
  maxLines: null,  // If this is null, there is no limit to the number of lines, and the text container will start with enough vertical space for one line and automatically grow to accommodate additional lines as they are entered.
  expands: true,  // If set to true and wrapped in a parent widget like [Expanded] or [SizedBox], the input will expand to fill the parent.
)

Jak sobie radzić z brakującą wewnętrzną wysokością TextField?

Zawiń TextFieldw IntrinsicHeightklasie, aby zapewnić dynamicznie obliczaną wewnętrzną wysokość elementu rozszerzalnego TextFielddo jego rodzica (na żądanie przez np. Flexbox).

tahesse
źródło
0

Oficjalny dokument stwierdza : maxLinesWłaściwość można ustawić na wartość null, aby usunąć ograniczenie liczby wierszy. Domyślnie jest to jeden, co oznacza, że ​​jest to jednowierszowe pole tekstowe.

UWAGA: maxLines nie może wynosić zero.

mickyliu
źródło
0

W widżecie TextFormField możesz ustawić minLines i maxLines, jeśli chcesz ustawić stałą liczbę wierszy. W przeciwnym razie możesz również ustawić maxLines na null.

TextFormField(
      minLines: 5,
      maxLines: 7,
      decoration: InputDecoration(
          hintText: 'Address',
          border: OutlineInputBorder(
              borderRadius: BorderRadius.all(Radius.circular(10.0)),
          ),
      ),
),
Dhrumil Shah
źródło