【问题标题】:Draw outside listview bounds in Flutter在 Flutter 中绘制列表视图边界之外的内容
【发布时间】:2020-07-08 01:49:26
【问题描述】:

我想将我的项目转换为比列表视图本身更大。 (重点导航的意图)

我的清单:

        Container(
          height: 100,
          child: ListView.builder(
            itemBuilder: (context, index) => HomeItem(title: '$index'),
            scrollDirection: Axis.horizontal,
          ),
        ),

我的物品:

class HomeItem extends StatelessWidget {
  final String title;
  final bool expand;

  const HomeItem({
    @required this.title,
    this.expand = false,
  });

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: ThemeDimens.padding8),
      child: Transform.scale(
        scale: expand ? 1.5 : 1,
        child: AnimatedContainer(
          width: 50,
          height: 100,
          color: expand ? ThemeColors.accent : ThemeColors.primary,
          duration: ThemeDurations.shortAnimationDuration(),
          child: Center(
            child: Text(title),
          ),
        ),
      ),
    );
  }
}

当前行为

预期行为

【问题讨论】:

  • 看看这个小部件,它应该可以解决问题:api.flutter.dev/flutter/widgets/OverflowBox-class.html
  • 我确实尝试过使用 OverFlowBox,但我无法弄清楚。我应该把它放在哪里?
  • OverflowBox 在这种情况下不起作用。我马上回复你。

标签: flutter flutter-layout flutter-animation flutter-listview


【解决方案1】:

如果您尝试使用 OverflowBox 或 Transform,项目的内容仍将被裁剪,并且不会被绘制到其边界框之外。但是可以使用Overlay 在列表顶部绘制一个元素并将其定位在特定的列表项上,虽然有点复杂。

class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver {
  final elements = List.generate(12, (i) => i);

  int selectedIndex;
  OverlayEntry overlayEntry;
  List<LayerLink> layerLinks;

  @override
  void initState() {
    super.initState();

    // Creating a layer link for each list cell
    layerLinks = List.generate(elements.length, (i) => LayerLink());
  }

  void createOverlayEntry(int i, BuildContext context) {
    // Removing an overlay entry, if there was one
    overlayEntry?.remove();

    final renderBox = context.findRenderObject() as RenderBox;
    final size = renderBox.size;
    final offset = renderBox.localToGlobal(Offset.zero);

    // Creating a new overlay entry linked to specific list element
    overlayEntry = OverlayEntry(
      builder: (context) => Positioned(
        left: 0,
        top: 0,
        child: CompositedTransformFollower(
          link: layerLinks[i],
          showWhenUnlinked: false,
          offset: Offset(-20, 0),
          child: Material(
            color: Colors.yellow,
            child: InkWell(
              onTap: () {
                setState(() {
                  selectedIndex = null;
                });

                overlayEntry?.remove();
                overlayEntry = null;
              },
              child: Container(
                alignment: Alignment.center,
                width: 70,
                height: elementHeight,
                child: Text('$i')
              ),
            )
          ),
        )
      )
    );

    // Inserting an entry
    Overlay.of(context).insert(overlayEntry);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Container(
        height: elementHeight,
        child: ListView.separated(
          scrollDirection: Axis.horizontal,
          itemCount: elements.length,
          itemBuilder: (c, i) {
            return CompositedTransformTarget(
              link: layerLinks[i],
              child: Material(
                color: Colors.red,
                child: InkWell(
                  onTap: () {
                    setState(() {
                      selectedIndex = i;
                    });

                    createOverlayEntry(i, context);
                  },
                  child: Container(
                    alignment: Alignment.center,
                    width: 30,
                    child: Text('${elements[i]}'),
                  ),
                ),
              ),
            );
          },
          separatorBuilder: (c, i) {
            return Container(width: 10, height: 10);
          },
        ),
      ),
    );
  }
}

【讨论】:

  • 干得好.. 从我这里投票 :) 但我相信 OP 要求在 y 轴上缩放按钮,而不是像你那样在 x 轴上缩放
  • 是的,我正在寻找一种解决方案,该解决方案也超出了您列表顶部的范围。 (Y 轴)这个解决方案和我最初发布的完全一样。
  • @KoenVanLooveren 我的解决方案也适用于 Y 轴。只需更改覆盖条目的 Y 偏移量(例如 Offset(-20, -20))
  • 老兄这是一个终极答案,我什至不知道这样的 api
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-16
  • 2018-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-15
  • 1970-01-01
相关资源
最近更新 更多