Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: safely call paintExtentOf #40

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

LinXunFeng
Copy link
Member

@LinXunFeng LinXunFeng commented Oct 8, 2024

insertLeading 方法中会调用传入的 paintExtentOf 方法获取 child 的绘制大小,但没有在调用前对 child.hasSize 进行判断,导致有时会出现瀑布流白屏的异常现象,进而无法继续正常使用。

final int? minLeadingIndex = crossAxisChildrenData.minLeadingIndex;
while (child != null && minLeadingIndex! < indexOf(child)) {
crossAxisChildrenData.insertLeading(
child: child, paintExtentOf: paintExtentOf);
child = childBefore(child);
}

image

PR 添加 child.hasSize 来安全调用 paintExtentOf 从而避免瀑布流白屏问题。

希望能尽快发布修复版本 ☕

@zmtzawqlp
Copy link
Member

有没有场景和简单例子能重现这个问题的?

@LinXunFeng
Copy link
Member Author

尝试过单独写个复现示例,但没能成功,只在我们自己项目里复现了~

@zmtzawqlp
Copy link
Member

最好是知道为什么,那个child 会没有layout,如果直接pass掉,是否会有其他问题?

@LinXunFeng
Copy link
Member Author

LinXunFeng commented Oct 10, 2024

可复现问题的代码

import 'dart:math';

import 'package:flutter/material.dart';
import 'package:waterfall_flow/waterfall_flow.dart';

class GridViewPage extends StatefulWidget {
  const GridViewPage({super.key});

  @override
  State<GridViewPage> createState() => _GridViewPageState();
}

class _GridViewPageState extends State<GridViewPage> {
  final int _count = 12;
  int _recommendCount = 20;

  late ScrollController _scrollController;

  @override
  void initState() {
    _scrollController = ScrollController();
    super.initState();
  }

  @override
  void dispose() {
    _scrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        controller: _scrollController,
        slivers: [
          _buildGridView(),
          _buildGridView(isRecommend: true),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            _recommendCount += 13;
          });
        },
        child: const Icon(Icons.refresh),
      ),
    );
  }

  Widget _buildGridView({
    bool isRecommend = false,
  }) {
    return SliverWaterfallFlow(
      // return SliverGrid(
      gridDelegate: SliverWaterfallFlowDelegateWithFixedCrossAxisCount(
        // gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
        mainAxisSpacing: 16,
        crossAxisSpacing: 10,
        // mainAxisExtent: 285,
      ),
      delegate: SliverChildBuilderDelegate(
        (BuildContext context, int index) {
          return Container(
            // 造成该问题的主要代码
            key: Key(randomValue()),
            color: Colors.white,
            alignment: Alignment.center,
            height: 285,
            child: Text(
              index.toString(),
              style: const TextStyle(
                color: Colors.black,
              ),
            ),
          );
        },
        childCount: isRecommend ? _recommendCount : _count,
      ),
    );
  }
}

String randomValue({int count = 3}) {
  String randomStr = Random().nextInt(10).toString();
  for (var i = 0; i < count; i++) {
    var str = Random().nextInt(10);
    randomStr = "$randomStr$str";
  }
  final timeNumber = DateTime.now().millisecondsSinceEpoch;
  final uuid = "$randomStr$timeNumber";
  return uuid;
}

复现步骤:运行后滚动到最后,点击 FloatingActionButton 即可复现

2024-10-10.16.02.48_.mov

那个child 会没有layout,如果直接pass掉,是否会有其他问题?

如录屏所示,仅位置变动,无其它问题。

2024-10-10.16.28.53_.mov

将代码中的 SliverWaterfallFlow 改回 SliverGrid 则一切正常。

2024-10-10.16.06.12_.mov

@zmtzawqlp
Copy link
Member

zmtzawqlp commented Oct 10, 2024

每一个 item 增加 随机 key 的作用是什么?

@LinXunFeng
Copy link
Member Author

同事对 visibility_detector 的封装,没指定就随机了~

@zmtzawqlp
Copy link
Member

同事对 visibility_detector 的封装,没指定就随机了~

就算有 key 。也应该对应 到 对应的 index 吧? 确实想不到这样写的意思是啥?

@zmtzawqlp
Copy link
Member

刚简单跑了下例子,虽然不会报错,但是会导致布局错乱,这个问题应该不是这样简单处理的。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants