Flutter: элементы исчезают из ListView при переключении фильтра назад и вперед и прокручивании полосы прокрутки при прокрутке - PullRequest
0 голосов
/ 13 февраля 2020

Когда я пытался реализовать простую ListView фильтрацию, я сталкивался с двумя трудностями.

  1. Когда элемент не удовлетворял правилам фильтрации, я сначала возвращал Container с нулевой высотой, и это работало, но когда я Отфильтруйте одну порцию элементов, затем прокрутите вниз, отключите фильтр и прокрутите назад, ранее отфильтрованные элементы больше не появляются:

filtering bug

Затем я вернулся Container с ростом 0,0001 и неожиданно решенная проблема:

filtering bug solved

Почему это сработало? Container s с высотой 0,0001 также невидимы, как Container с нулевой высотой. И есть ли лучшее решение?

Когда я фильтрую единицы и сотни, Scrollbar дергается при прокрутке:

scrollbar twitching

Как сделать Scrollbar go сглаживать при применении фильтра?

код в DartPad

код:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final items = List.generate(1000, (index) => '$index');
  var filterOptions = List.of(IntType.values);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: buildBody(),
        appBar: AppBar(
          title: Text('Simple filtering'),
          bottom: buildAppBarBottom(),
        ),
      ),
    );
  }

  Widget buildBody() {
    return Scrollbar(                       // second question
      child: ListView.builder(
        itemCount: items.length,
        itemBuilder: (context, index) {
          final item = items[index];

          if (filterOptions.any((option) => option.length == item.length)) {
            return ListTile(title: Text(item));
          }

          return Container(height: 0.0001); // first question
        },
      ),
    );
  }

  PreferredSizeWidget buildAppBarBottom() {
    return PreferredSize(
      preferredSize: Size.fromHeight(50),
      child: Padding(
        padding: EdgeInsets.all(8),
        child: Row(
          children: IntType.values.map((option) {
            return Padding(
              padding: EdgeInsets.symmetric(horizontal: 4),
              child: FilterChip(
                selectedColor: Colors.white,
                selected: filterOptions.contains(option),
                onSelected: (isSelected) {
                  setState(() {
                    if (isSelected) {
                      filterOptions.add(option);
                    } else {
                      filterOptions.remove(option);
                    }
                  });
                },
                label: Text(option.name),
              ),
            );
          }).toList(),
        ),
      ),
    );
  }
}

class IntType {
  static const IntType ones = const IntType._('Ones', 1);
  static const IntType tens = const IntType._('Tens', 2);
  static const IntType hundreds = const IntType._('Hundreds', 3);

  final String name;
  final int length;

  const IntType._(this.name, this.length);

  static const values = [
    IntType.ones,
    IntType.tens,
    IntType.hundreds,
  ];
}


...