flutter - SliverList / SliverChildBuilderDelegate предоставляет начальный индекс или разрешает отрицательные индексы

В настоящее время я создаю представление календаря во Flutter, используя SliverList и SliverChildBuilderDelegate, так что мне не нужно отображать каждый элемент календаря сразу.

Первая дата - это время эпохи, 1 января 1970 года, а последняя дата - это нечетное количество времени, вычисленное после сегодняшней даты.

Моя проблема заключается в том, что когда я впервые визуализирую представление, я хочу, чтобы оно отображало представление, начиная с сегодняшнего дня, а не 1 января 1970 года. Однако, если сегодня у меня есть индексы 0, отрицательные индексы не допускаются (или не предоставляются) для делегат строителя, чтобы вы не могли прокрутить вверх с этой даты. Вы также не можете предоставить начальный индекс, насколько я могу судить, конструктору или списку, поэтому я не могу указать время эпохи как индексы 0, так как список просто начинается там, что делает довольно ужасные опыт! Я не совсем уверен, что делать дальше.

У кого-нибудь есть предложения?


person Sam Markoe    schedule 31.05.2018    source источник
comment
Возможный дубликат Как прокручивать элемент в ListView, чтобы он был видно?   -  person creativecreatorormaybenot    schedule 05.06.2018


Ответы (2)


Я не знаю простого способа сделать это, нет параметра initialPositition ни в ListView, ни в SliverList. Причина, по которой я могу думать, заключается в том, что списки представляют собой серию виджетов, встроенных в ScrollView, так что для установки начального элемента вам необходимо знать точное смещение прокрутки этого элемента.

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

Однако вы можете упростить задачу, если заранее знаете высоту всех элементов списка или можете установить для них фиксированную высоту с помощью поля ListView.itemExtent или SliverFixedExtentList.


Если вы заранее знаете (или задали) высоту элементов списка, вы можете установить начальный элемент с помощью initialScrollOffset в вашем ScrollController. Вот пример с ListView.

@override
Widget build(BuildContext context) {
  final _itemExtent = 56.0; // I know item heights beforehand
  final generatedList = List.generate(500, (index) => 'Item $index');

  return ListView(
    controller: ScrollController(initialScrollOffset: _itemExtent * 401),
    children: generatedList
        .map((index) =>
            ListTile(title: Text(index, style: TextStyle(fontSize: 20.0))))
        .toList(),
  );
}

Or in a SliverList.

@override
Widget build(BuildContext context) {
  final _itemExtent = 56.0;
  final generatedList = List.generate(500, (index) => 'Item $index');

  return CustomScrollView(
    controller: ScrollController(initialScrollOffset: _itemExtent * 401),
    slivers: [
      SliverFixedExtentList(
        itemExtent: _itemExtent,  // I'm forcing item heights
        delegate: SliverChildBuilderDelegate(
          (context, index) => ListTile(
                title: Text(
                  generatedList[index],
                  style: TextStyle(fontSize: 20.0),
                ),
              ),
          childCount: generatedList.length,
        ),
      ),
    ],
  );
}

В обоих случаях это результат, когда вы впервые открываете приложение.

введите описание изображения здесь

person Edman    schedule 31.05.2018
comment
Да, это моя проблема, поскольку, хотя все заголовки месяца / недели имеют одинаковую высоту, сами виджеты дня имеют переменные размеры в зависимости от того, сколько элементов в них есть. - person Sam Markoe; 01.06.2018
comment
Но следует ли это по-прежнему хорошо организованному образцу? Если высота дневного виджета является функцией количества элементов, которые у него есть, вы все равно можете вычислить и кэшировать его самостоятельно (и обновить при необходимости), а затем использовать его во время сборки. - person Edman; 01.06.2018
comment
Ах нет, подождите, я понял. Я поиграю с этим. Спасибо! - person Sam Markoe; 01.06.2018

SliverList принимает параметр делегата, который предоставляет элементы в списке по мере их прокрутки до представления.

Вы можете указать фактический список дочерних элементов с помощью SliverChildListDelegate или лениво построить их с помощью SliverChildBuilderDelegate.

SliverList(
    delegate: SliverChildListDelegate(
      [
        Container(color: Colors.red, height: 150.0),
        Container(color: Colors.purple, height: 150.0),
        Container(color: Colors.green, height: 150.0),
      ],
    ),
);
// This builds an infinite scrollable list of differently colored 
// Containers.
SliverList(
    delegate: SliverChildBuilderDelegate((BuildContext context, int index) {
      // To convert this infinite list to a list with three items,
      // uncomment the following line:
      // if (index > 3) return null;
      return Container(color: getRandomColor(), height: 150.0);
    },
    // Or, uncomment the following line:
    // childCount: 3,
  ),
);

введите описание изображения здесь

Ссылки: http://flutterexamples.com/#textfield

person Paresh Mangukiya    schedule 09.12.2020