Repository: flutter
Issue: Support ValueWidgetBuilder for ListView.builder with optionally bi-directional
Labels: c: new feature,framework,f: scrolling,c: proposal,P3,team-framework,triaged-framework

## Use case

<!--
     Please tell us the problem you are running into that led to you wanting
     a new feature.

     Is your feature request related to a problem? Please give a clear and
     concise description of what the problem is.

     Describe the alternative solutions you've considered. Is there a package
     on pub.dev/flutter that already solves this?
-->

I am implementing a **bi-directional infinite** `ListView`. The data to build the item is a **date**.

Behind the scene, `ListView.builder` is using `IndexedWidgetBuilder`, which uses positive integers starting from zero to generate items. I think it satisfies almost normal cases in real life.

For more innovative ideas, it would be not enough.
I suggest to support [`ValueWidgetBuilder`](https://api.flutter.dev/flutter/widgets/ValueWidgetBuilder.html) instead of `IndexedWidgetBuilder`, which is more powerful than the current implementation and will cover also the current one.

## Proposal

<!--
     Briefly but precisely describe what you would like Flutter to be able to do.

     Consider attaching images showing what you are imagining.

     Does this have to be provided by Flutter directly, or can it be provided
     by a package on pub.dev/flutter? If so, maybe consider implementing and
     publishing such a package rather than filing a bug.
-->

I would suggest to improve current `ListView.builder` and keep default behavior as current implementation to keep backward compatible.

Below are some proposal snippets for the new `ListView.builder`.

```
ListView.builder<DateTime>(
  // Use to build the initial item and as a seed to generate other value for other items.
  initialValue: DateTime.now(),

  // Maybe, there's better ways than having 2 methods nextValue and previousValue?

  // This method is used for building item after the initial item.
  // Assuming scroll direction is vertical and reverse is false,
  // * nextValue is used for building item below the initial item.
  // * if function is not provided, it's not possible to scroll down.
  nextValue: (value) {
    return value.add(new Duration(days: 1);
  },

  // This method is used for building item before the initial item.
  // Assuming scroll direction is vertical and reverse is false,
  // * previousValue is used for building item above the initial item.
  // * if function is not provided, it's not possible to scroll up.
  previousValue: (value) {
    return value.subtract(new Duration(days: 1);
  },

  itemBuilder: (context, value) {
    // Return widget for the given value
    // Return null to indicate the last item
    return Text('$value');
  }
)
```

The default `ListView.builder` should work exactly like current implementation. The current implementation is just a special case of new implementation:
```
ListView.builder<int>(
  initialValue: 0,

  nextValue: (value) {
    return value + 1;
  },

  // Assuming scroll direction is vertical and reverse is false, and here we do not provide a function.
  // It means that it's not possible to scroll up.
  previousValue: null,

  itemBuilder: (context, value) {
    return Text('$value');
  }
)
```

If it's difficult to have backward compatible, we should create a new constructor.

If it works for ListView, GridView should follow this new implementation.