Показывать счетчик количества скрытых элементов при переполнении в виджете флаттер-строки

Может ли кто-нибудь помочь реализовать эту функцию Gmail, которая показывает счетчик количества электронных писем, скрытых, когда список адресов электронной почты становится большим? Я хочу реализовать это в виджете строки, где вместо прокручиваемого количества дополнительных элементов отображается при переполнении. Gmail показывает счетчик +15 для скрытых писем

2 ответа

Мне было любопытно попробовать добиться того же эффекта, как я просил.

На всякий случай, если кто-то хочет начать писать собственный, то приведенный ниже код может помочь.

Вот мой Code, Не стесняйтесь давать любые предложения, (На данный момент delete кнопка в микросхемах не работает из-за какой-то логической проблемы, заставлю работать в другой день)

      import 'package:flutter/material.dart';

class Demo3 extends StatefulWidget {
  @override
  _Demo3State createState() => _Demo3State();
}

class _Demo3State extends State<Demo3> {
  String temp = "";
  bool showChips = false;
  List<Widget> chipsList = new List();
  TextEditingController textEditingController = new TextEditingController();
  final _focusNode = FocusNode();
  int countChipsToDeleteLater = 0;

  @override
  void initState() {
    super.initState();
    _focusNode.addListener(() {
      print("Has focus: ${_focusNode.hasFocus}");
      if (!_focusNode.hasFocus) {
        showChips = false;
        setState(() {});
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: GestureDetector(
        onTap: () {
          FocusScope.of(context).requestFocus(new FocusNode());
        },
        child: new Container(
          height: 500,
          child: new Center(
            child: Container(
              width: 300,
              child: !showChips
                  ? Row(
                      children: [
                        buildTextField(),
                        showNumberWidgetIfAny(),
                      ],
                    )
                  : Center(
                      child: Wrap(
                        children: [
                          Wrap(
                            children: buildChips(),
                          ),
                          buildTextField(),
                        ],
                      ),
                    ),
            ),
          ),
        ),
      ),
    );
  }

  buildChips() {
    return chipsList;
  }

  buildTextField() {
    return Container(
      width: 200,
      child: new TextField(
        showCursor: true,
        focusNode: _focusNode,
        autofocus: true,
        cursorColor: Colors.black,
        style: new TextStyle(fontSize: 22.0, color: Colors.black),
        controller: textEditingController,
        // decoration: InputDecoration.collapsed(
        //   hintText: "",
        // ),
        onChanged: (value) {
          if (value.contains(" ")) {
            checkWhatToStoreInChips(value, countChipsToDeleteLater);
            textEditingController.clear();
            setState(() {
              showChips = true;
            });
            countChipsToDeleteLater++;
          }
        },
      ),
    );
  }

  checkWhatToStoreInChips(String val, int chipsIndex) {
    temp = "";
    for (int i = 0; i < val.length; i++) {
      if (val[i] == " ") {
        break;
      }
      temp = temp + val[i];
    }
    addToChips(temp, chipsIndex);
  }

  addToChips(String tmp, int chipsIndex) {
    chipsList.add(Chip(
      // onDeleted: () {
      //   if (chipsList.length == 0) {
      //     countChipsToDeleteLater = 0;
      //   }
      //   chipsList.removeAt(chipsIndex);
      //   print(chipsList.length);
      //   print(chipsIndex);
      //   setState(() {});
      // },
      avatar: CircleAvatar(
        backgroundColor: Colors.grey.shade800,
        child: Text(tmp[0]),
      ),
      label: Text(temp),
    ));
  }

  showNumberWidgetIfAny() {
    int len = chipsList.length;
    if (len >= 1) {
      return GestureDetector(
        onTap: () {
          showChips = true;
          setState(() {});
        },
        child: new Container(
          decoration: BoxDecoration(
            shape: BoxShape.circle,
            color: Colors.blue,
          ),
          child: Padding(
            padding: const EdgeInsets.all(8.0),
            child: new Text(
              "${chipsList.length.toString()} ",
              style: new TextStyle(color: Colors.white, fontSize: 22),
            ),
          ),
        ),
      );
    }
    return Container();
  }
}

Как это устроено:

  1. Напишите что-нибудь в текстовом поле, затем нажмите пробел, значение showChips boolean станет истинным.
  2. onChanged обнаружит пробел и отправит строку функции.
  3. Эта функция извлечет строку перед пробелом, а затем добавит строку в чип,
  4. Наконец, чип будет добавлен в список микросхем.
  5. У нас будет логическая переменная, чтобы проверить, находится ли текстовое поле в фокусе и когда показывать текстовое поле и виджет числа (виджет, который будет вести подсчет общего количества фишек, как вы задали в своем вопросе) или когда показывать список фишек и текстовое поле завернутый в виджет обертки.
  6. Вы можете поиграть, изменив оформление текстового поля на свернутое, чтобы оно выглядело так же, как в Gmail.

Отметьте этот пакет, если вы хотите легко использовать настраиваемый пакет.

Я столкнулся с аналогичной проблемой. Я нашел способ реализовать текст счетчика переполнения. Образец изображения В основном вам нужно нарисовать текст переполнения и получить его ширину, как показано ниже.

      final TextPainter textPainter = TextPainter(
  text: TextSpan(text: text, style: style),
  textDirection: TextDirection.ltr,
  textScaleFactor: WidgetsBinding.instance.window.textScaleFactor,
)..layout();

var textSize = textPainter.size;
textSize.width;

Затем вычтите это из доступной ширины. Назовем это х. Затем создайте сумму ширины для каждого элемента строки (используя упомянутый выше метод TextPainter.layout()), пока его значение не станет меньше x. Таким образом, вы будете знать, сколько элементов может отображаться в строке.

Я создал библиотеку Flutter , чтобы помочь с этим.

Другие вопросы по тегам