如何使用Flutter创建可滚动的包装视图?

时间:2017-06-10 00:29:56

标签: dart flutter

我希望显示有限数量的项目,并在用户向任一方向滚动时进行换行。我该怎么做?

2 个答案:

答案 0 :(得分:0)

你无法用无限长度ListView.builder轻松解决这个问题,因为它只能向一个方向发展。如果要在两个方向上进行换行,可以模拟双向换行,其中两个视口的Stack向相反的方向移动。

screenshot

import 'package:flutter/material.dart';

void main() {
  runApp(new MaterialApp(
    home: new HomePage(),
  ));
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Wrapping List View'),
      ),
      body: new WrappingListView.builder(
        itemCount: 10,
        itemBuilder: (BuildContext context, int index) {
          return new Card(
            child: new Container(
              height: 50.0,
              color: Colors.blue.withOpacity(index / 10),
              child: new Center(
                child: new Text('Card $index')
              ),
            ),
          );
        },
      ),
    );
  }
}

class WrappingListView extends StatefulWidget {

  factory WrappingListView({ Key key, List<Widget> children }) {
    return new WrappingListView.builder(
      itemCount: children.length,
      itemBuilder: (BuildContext context, int index) {
        return children[index % children.length];
      },
    );
  }

  WrappingListView.builder({ Key key, this.itemBuilder, this.itemCount })
    : super(key: key);

  final int itemCount;
  final IndexedWidgetBuilder itemBuilder;

  WrappingListViewState createState() => new WrappingListViewState();
}

class UnboundedScrollPosition extends ScrollPositionWithSingleContext {
  UnboundedScrollPosition({
    ScrollPhysics physics,
    ScrollContext context,
    ScrollPosition oldPosition,
  }) : super(physics: physics, context: context, oldPosition: oldPosition);

  @override
  double get minScrollExtent => double.negativeInfinity;
}

class UnboundedScrollController extends ScrollController {
  @override
  UnboundedScrollPosition createScrollPosition(
    ScrollPhysics physics,
    ScrollContext context,
    ScrollPosition oldPosition,
  ) {
    return new UnboundedScrollPosition(
      physics: physics,
      context: context,
      oldPosition: oldPosition,
    );
  }
}

class WrappingListViewState extends State<WrappingListView> {
  UnboundedScrollController _controller = new UnboundedScrollController();
  UnboundedScrollController _negativeController = new UnboundedScrollController();

  @override
  void initState() {
    _controller.addListener(() {
      _negativeController.jumpTo(
        -_negativeController.position.extentInside -
        _controller.position.pixels,
      );
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Stack(
      children: <Widget>[
        new CustomScrollView(
          physics: new AlwaysScrollableScrollPhysics(),
          controller: _negativeController,
          reverse: true,
          slivers: <Widget>[
            new SliverList(
              delegate: new SliverChildBuilderDelegate(
                (BuildContext context, int index) {
                  return widget.itemBuilder(
                    context,
                    (widget.itemCount - 1 - index) % widget.itemCount,
                  );
                }
              ),
            ),
          ],
        ),
        new ListView.builder(
          controller: _controller,
          itemBuilder: (BuildContext context, int index) {
            return widget.itemBuilder(context, index % widget.itemCount);
          },
        ),
      ],
    );
  }
}

答案 1 :(得分:0)

截至2018年12月,您可以(与合适的构建器一起使用):https://pub.dartlang.org/packages/infinite_listview