如何使用Flutter制作可滚动的包装视图? [英] How can I make a scrollable wrapping view with Flutter?

查看:173
本文介绍了如何使用Flutter制作可滚动的包装视图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to display a finite number of items and wrap when the user scrolls in either direction. How do I do this?

推荐答案

使用无限长的 ListView无法轻松解决此问题.builder ,因为它只沿一个方向运行。如果要双向包裹,可以使用两个方向相反的视口的 Stack 来模拟双向包裹。

You can't easily solve this with an infinite-length ListView.builder because it only goes in one direction. If you want to wrap in both directions, it is possible to simulate bidirectional wrapping with a Stack of two viewports going in opposite directions.

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);
          },
        ),
      ],
    );
  }
}

这篇关于如何使用Flutter制作可滚动的包装视图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆