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

Flutter中Slidable结合ShowCase组件出现RenderBox布局渲染异常

Flutter Slidable与ShowCase结合报错RenderBox was not laid out的解决方法

问题场景

在Flutter开发中结合Slidable和ShowCase组件时,预期Slidable展开后ShowCase能展示预设引导内容,但运行时抛出如下断言错误:

======== Exception caught by rendering library =====================================================
The following assertion was thrown during paint():
RenderBox was not laid out: RenderClipRect#af542
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1972 pos 12: 'hasSize'

错误原因

Slidable默认处于收起状态,其endActionPane内的SlidableAction组件并未完成布局(无尺寸信息),而initState中直接调用startShowCase时,ShowCase尝试获取这些未布局组件的位置和尺寸,导致渲染断言失败。

解决方案

需先确保Slidable的ActionPane完全展开,待内部组件完成布局后,再启动ShowCase引导。通过SlidableController控制Slidable的展开状态,并在展开完成后延迟启动ShowCase即可解决。

修改后的组件代码

import 'package:flutter/material.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:loginmod/utils/app_colors.dart';
import 'package:showcaseview/showcaseview.dart';

class ShowCaseSalesTile extends StatefulWidget {
  final GlobalKey shareKey = GlobalKey();
  final GlobalKey printKey = GlobalKey();

  ShowCaseSalesTile({
    Key? key,
  }) : super(key: key);

  @override
  State<ShowCaseSalesTile> createState() => _ShowCaseSalesTileState();
}

class _ShowCaseSalesTileState extends State<ShowCaseSalesTile> {
  late SlidableController _slidableController;

  @override
  void initState() {
    _slidableController = SlidableController();
    super.initState();

    WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
      // 先展开Slidable右侧操作面板
      await _slidableController.openEndActionPane();
      // 延迟确保组件完成布局后启动ShowCase
      Future.delayed(const Duration(milliseconds: 300), () {
        ShowCaseWidget.of(context)
            .startShowCase([widget.shareKey, widget.printKey]);
      });
    });
  }

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

  @override
  Widget build(BuildContext context) {
    return Slidable(
      controller: _slidableController, // 绑定控制器
      endActionPane: ActionPane(
        motion: const ScrollMotion(),
        children: [
          Showcase(
            key: widget.shareKey,
            title: "Share Data",
            description: "Share Bill With Others",
            child: SlidableAction(
              onPressed: (context) {},
              backgroundColor: AppColors.secondaryColor,
              foregroundColor: Colors.white,
              icon: Icons.share,
            ),
          ),
          Showcase(
            key: widget.printKey,
            title: "Print Bill",
            description: "Print Bill",
            child: SlidableAction(
              onPressed: (context) {},
              backgroundColor: AppColors.primaryColor,
              foregroundColor: Colors.white,
              icon: Icons.print,
            ),
          ),
        ],
      ),
      child: InkWell(
        onTap: () {},
        child: Padding(
            padding: const EdgeInsets.all(8.0),
            child: ListTile(title: Text("Test 1"))),
      ),
    );
  }
}

关键说明

  • 用SlidableController精准控制Slidable的展开操作,确保操作面板先被打开。
  • 延迟启动ShowCase是为了给组件足够的布局时间,避免再次触发未布局断言,延迟时间可根据实际场景调整。
  • 在dispose方法中销毁SlidableController,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 16:12:38