Flutter - Dynami c суффикс текста для TextField? - PullRequest
1 голос
/ 09 февраля 2020

Я создаю простое приложение для звуковой карты во Flutter, которое включает панель поиска в верхней части приложения.

В точке, где активирован поиск, интересный бит дерева виджетов выглядит так: следует:

home: Scaffold(
          appBar: AppBar(
            title: new TextField(
              controller: _filter,
              decoration: new InputDecoration(
                prefixIcon: new Icon(Icons.search, color: Colors.white),
                hintText: 'Search...'
          ),

Когда текст вводится в строку поиска, слушатель на _filter обновляет список цитат, который используется для построения тела приложения. Это все работает нормально.

Однако мне бы хотелось, чтобы приложение показывало счетчик возвращаемых результатов, и, поскольку оно находится в моей строке заголовка, я бы хотел, чтобы оно совпало с сама строка, что-то вроде:

enter image description here

Вещи, которые я пробовал, все в пределах настройки InputDecoration:

  • suffixText - это оформлено правильно и в нужном месте, однако оно не обновляется при изменении _filter, потому что я не восстанавливаю TextField каждый раз (и я не могу сделать это, так как он испортился что было набрано).
  • Установка suffix на полный TextField виджет с собственным контроллером. Это автоматически обновляется, но по какой-то причине скрывает мой фактический текст поиска. Я попытался сделать фон прозрачным, но это не помогло - new TextField(controller: _searchCountController, readOnly: true, textAlign: TextAlign.end, style: TextStyle(backgroundColor: Colors.transparent),). На скриншоте ниже я набрал 'w', который обновил счет до 84 (но я не вижу 'w', который набрал ...)

enter image description here

  • Настройка counter вместо suffix. Я могу заставить это автоматически обновляться и не скрывать мой поиск, но это появляется под строкой поиска, которая заставляет все это выглядеть невнятным. Не совсем подходит для чего-то, что находится в строке заголовка.

enter image description here

Любые предложения о том, как я могу добиться того, чего я добиваюсь ? Очень плохо знакомый с Флаттером, настолько вероятный, что я упустил нечто очевидное. Надеюсь, что есть простое решение:)

Ответы [ 2 ]

0 голосов
/ 13 февраля 2020

Ну, как и ожидалось, оказалось, что я упустил что-то очевидное, и было простое решение. У меня были проблемы с получением простого suffixText для обновления, потому что я в конечном итоге кэшировал компонент и поэтому не давал Flutter шанса повторно его отрендерить.

В случае, если это кому-нибудь поможет, я следовал этому сообщению , чтобы реализовать панель поиска. Они используют шаблон для хранения виджета _appBarTitle, который изменяется только тогда, когда поиск инициируется и отменяется. Я отошел от этого подхода, вместо этого имея простое логическое значение _searching и позволяя flutter делать все остальное:

Widget _buildAppBar() {
    if (_searching) {
      return new TextField(
          controller: _filter,
          decoration: new InputDecoration(
            prefixIcon: new Icon(Icons.search, color: Colors.white),
            hintText: 'Search...',
            suffixText: '${_filteredQuotes.length}',
          ),
          autofocus: true,
          style: TextStyle(color: Colors.white));
    } else {
      return new Text('Pocket Scat');
    }
  }

При таком подходе мне вообще не нужно указывать компонент для суффикса , Он также имеет преимущество автоматического извлечения hintColor из стиля моего приложения.

0 голосов
/ 12 февраля 2020

Вы можете скопировать и запустить полный код ниже
Вы можете использовать Row с Expanded(TextField) и Text()
фрагмент кода

AppBar(
          title: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: <Widget>[
          Expanded(
            child: TextField(
                controller: _filter,
                decoration: InputDecoration(
                  prefixIcon: Icon(Icons.search, color: Colors.white),
                  hintText: 'Search...',
                )),
          ),
          Text('$_counter'),
        ],
      ))

рабочая демонстрация

enter image description here

полный код

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  TextEditingController _filter = TextEditingController();
  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          title: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: <Widget>[
          Expanded(
            child: TextField(
                controller: _filter,
                decoration: InputDecoration(
                  prefixIcon: Icon(Icons.search, color: Colors.white),
                  hintText: 'Search...',
                )),
          ),
          Text('$_counter'),
        ],
      )),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}
...