Flutter IndexedWidgetBuilder с ListView.builder с динамическим c количество элементов? - PullRequest
1 голос
/ 04 февраля 2020

Скажем, я извлекаю некоторые данные из API и хочу поместить их в ListView.builder. Я хочу выполнить отложенную загрузку, потому что в любое время на экране будут отображаться только три элемента. Скажем, данные выглядят примерно так: нам не гарантировано получить все заголовки, и мы не знаем, сколько элементов в contents.

header: HeaderOne
contents: [ItemOne, ItemTwo, ItemThree]

header: HeaderTwo
contents: [ItemOne]

header: HeaderThree // don't display this because contents is empty
contents: [] // don't display this because contents is empty

header: HeaderFour
contents: [ItemOne, ItemTwo]

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

HeaderOne
ItemOne
ItemTwo
ItemThree
HeaderTwo
ItemOne
HeaderFour
ItemOne
ItemTwo

Мое itemBuilder свойство в ListView.builder () становится чем-то ужасным. Вот некоторый псевдокод:

itemBuilder: (BuildContext context, index i) {
  if (i == 0 && data.hasHeaderOne) { return _buildHeaderOne(); }
  else if (i == 0 && !data.hasHeaderOne) { return _buildHeaderTwo(); }
  else if (i == 1 && data.hasHeaderOne { return _buildContents(headerOneContents[0]); }
  else if (i == (1 + data.headerOneContents.length) && data.hasHeaderOne && data.hasHeaderTwo) { return _buildContents(headerTwoContents[i+someNumberIHaveToCalculate]); }
  ...
}

Определенно, есть лучший способ сделать это! Я рассмотрел вложение ListView.builder (), но не уверен, как это влияет на производительность или прокрутку.

Цель состоит в том, чтобы использовать конструктор, когда я не знаю, по какому индексу будет индекс каждого элемента. Я мог бы подсчитать общее количество элементов (в данном примере 9), но я не понимаю, как это поможет без написания сложного кода if-else.

1 Ответ

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

Я закончил тем, что сделал это, создав список строителей виджетов вместо виджетов. Например, что-то вроде:

typedef WidgetBuilder Widget Function();

...

final itemBuilder = <WidgetBuilder>[
if (data.hasHeaderOne) () => _buildHeaderOne(),
for (item in data.headerOneContents) () => _buildContents(item),
...
];

return ListView.builder(
  itemCount: itemBuilder.length, 
  itemBuilder: (_, item) => itemBuilder[item](),
);
...