PageView.custom constructor

PageView.custom({Key key, Axis scrollDirection: Axis.horizontal, bool reverse: false, PageController controller, ScrollPhysics physics, bool pageSnapping: true, ValueChanged<int> onPageChanged, @required SliverChildDelegate childrenDelegate, DragStartBehavior dragStartBehavior: DragStartBehavior.start })

Creates a scrollable list that works page by page with a custom child model.

This PageView uses a custom SliverChildBuilderDelegate to support child reordering.
class MyPageView extends StatefulWidget {
  @override
  _MyPageViewState createState() => _MyPageViewState();
}

class _MyPageViewState extends State<MyPageView> {
  List<String> items = <String>['1', '2', '3', '4', '5'];

  void _reverse() {
    setState(() {
      items = items.reversed.toList();
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: PageView.custom(
          childrenDelegate: SliverChildBuilderDelegate(
            (BuildContext context, int index) {
              return KeepAlive(
                data: items[index],
                key: ValueKey<String>(items[index]),
              );
            },
            childCount: items.length,
            findChildIndexCallback: (Key key) {
              final ValueKey valueKey = key;
              final String data = valueKey.value;
              return items.indexOf(data);
            }
          ),
        ),
      ),
      bottomNavigationBar: BottomAppBar(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            FlatButton(
              onPressed: () => _reverse(),
              child: Text('Reverse items'),
            ),
          ],
        ),
      ),
    );
  }
}

class KeepAlive extends StatefulWidget {
  const KeepAlive({Key key, this.data}) : super(key: key);

  final String data;

  @override
  _KeepAliveState createState() => _KeepAliveState();
}

class _KeepAliveState extends State<KeepAlive> with AutomaticKeepAliveClientMixin{
  @override
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Text(widget.data);
  }
}

Implementation

PageView.custom({
  Key key,
  this.scrollDirection = Axis.horizontal,
  this.reverse = false,
  PageController controller,
  this.physics,
  this.pageSnapping = true,
  this.onPageChanged,
  @required this.childrenDelegate,
  this.dragStartBehavior = DragStartBehavior.start,
}) : assert(childrenDelegate != null),
     controller = controller ?? _defaultPageController,
     super(key: key);