You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何翻转SliverGrid的X轴以修正双向懒加载网格的左右顺序

解决方法

我们通过两次X轴翻转即可修正上半部分网格的排列顺序,不需要提前获取每行单元格数量,也不需要额外依赖:

  1. 翻转整个上半部分SliverGrid的X轴,让每行元素从左到右按正确顺序排列
  2. 翻转每个子元素的X轴,抵消网格翻转带来的内容倒置

修改后的BidirectionalGridView完整代码如下:

import 'package:flutter/material.dart';

class BidirectionalGridView extends StatelessWidget {
  static const Key centerKey = ValueKey("CENTER");
  final SliverGridDelegate gridDelegate;
  final IndexedWidgetBuilder itemBuilder;
  final int upperItemCount;
  final int lowerItemCount;

  const BidirectionalGridView({
    required this.gridDelegate,
    required this.itemBuilder,
    required this.upperItemCount,
    required this.lowerItemCount,
    Key? key,
  }) : super(key: key);

  int get totalItemCount => upperItemCount + lowerItemCount;

  @override
  Widget build(BuildContext context) {
    return Scrollable(
      axisDirection: AxisDirection.down,
      viewportBuilder: (context, position) {
        return Builder(builder: (context) {
          return Viewport(
              center: centerKey,
              offset: position,
              anchor: 0,
              slivers: [
                // 仅修改上半部分SliverGrid逻辑
                SliverTransform(
                  transform: Matrix4.identity()..scale(-1.0, 1.0, 1.0),
                  child: SliverGrid(
                    gridDelegate: gridDelegate,
                    delegate: SliverChildBuilderDelegate(
                        (BuildContext context, int index) {
                      // 子元素二次翻转恢复内容正常显示
                      return Transform(
                        transform: Matrix4.identity()..scale(-1.0, 1.0, 1.0),
                        alignment: Alignment.center,
                        child: itemBuilder(context, upperItemCount - 1 - index),
                      );
                    }, childCount: upperItemCount),
                  ),
                ),
                SliverGrid(
                  key: centerKey,
                  gridDelegate: gridDelegate,
                  delegate: SliverChildBuilderDelegate(
                      (BuildContext context, int index) {
                    return itemBuilder(context, upperItemCount + index);
                  }, childCount: lowerItemCount),
                ),
              ]);
        });
      },
    );
  }
}

如果你更偏好无变换的实现方式,也可以用Directionality组件实现完全相同的效果,上半部分替换代码如下:

SliverDirectionality(
  textDirection: TextDirection.rtl,
  child: SliverGrid(
    gridDelegate: gridDelegate,
    delegate: SliverChildBuilderDelegate(
        (BuildContext context, int index) {
      return Directionality(
        textDirection: TextDirection.ltr,
        child: itemBuilder(context, upperItemCount - 1 - index),
      );
    }, childCount: upperItemCount),
  ),
)

两种方案都适配所有SliverGridDelegate配置,不需要提前知道网格交叉轴的单元格数量。

内容的提问来源于stack exchange,提问作者s0me1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 04:06:01