How to give dynamic height to SliverToBoxAdapter inside NestedScrollView ? (throws the `hasSize` issue)

179 Views Asked by At

I am using a NestedScrollView , which has SliverToBoxAdapter and SliverPersistentHeader in it's headerSliverBuilder

Until or unless I give a height to the "Container" widget inside the child of 'BlocProvider the `SliverToBoxAdapter` throws the "RenderBox was not laid out" issue

Error

I/flutter: The following exception was thrown 1. Library -: rendering library, 2. isSilent -: false, 3. Exception -: RenderBox was not laid out: RenderSemanticsAnnotations#274b0 relayoutBoundary=up12 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE 'package:flutter/src/rendering/box.dart': Failed assertion: line 1966 pos 12: 'hasSize': I/flutter: 'package:flutter/src/rendering/box.dart': Failed assertion: line 1966 pos 12: 'hasSize': RenderBox was not laid out: RenderSemanticsAnnotations#274b0 relayoutBoundary=up12 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE I/flutter: #0
_AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:51:61) #1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:40:5) #2 RenderBox.size (package:flutter/src/rendering/box.dart:1966:12) #3 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:123:21) #4 RenderObject.layout (package:flutter/src/rendering/object.dart:2395:7) #5 RenderBox.layout (package:flutter/src/rendering/box.dart:2386:11) #6 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:122:14) #7 RenderObject.layout (package:flutter/src/rendering/object.dart:2395:7) #8 RenderBox.layout (package:flutter/src/rendering/box.dart:2386:11) #9 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:122:14) #10 RenderObject.layout (package:flutter/src/rendering/object.dart:2395:7) #11 RenderBox.layout (package:flutter/src/rendering/box.dart:2386:11) #12 RenderProxyBoxMixin.performLayout (package

The widgets inside the SliverToBoxAdapter are BlocProvider, BlocBuilder etc, due to which I guess SliverToBoxAdapter is not able to calculate the height of its children,

Requirement -> To Keep the SliverToBoxAdapter dynamically adjustable to whatever height is given by it's children, it should adjust according to that, without providing a specific height

Code

Scaffold(
      backgroundColor: IndColors.darkBlue.getHexColor(),
      body: SafeArea(
        child: DefaultTabController(
          initialIndex: 1, 
          length: 3, 
          child: NestedScrollView(
            controller: context.read<MiniAppViewController>().miniAppScrollController,
            headerSliverBuilder: (context, innerBoxIsScrolled) => [
              SliverToBoxAdapter(child: widget.mastheadWidget),
              SliverPersistentHeader(
                delegate: _SliverAppBarDelegate(widget.tabbedWidget.tabBarWidget),
                pinned: true,
              ),
            ],
            body: TabBarView(
              children: widget.miniAppResponse?.miniApp?.tabs?.map((element) {
                    return LazyBaseWidgetViewParent(
                      api: element?.endpoint ?? StringConstants.empty,
                    );
                  }).toList() ??
                  [],
            ),
          ),
        ),
      ),
    );

Widget inside SliverToBoxAdapter (widget.mastheadWidget)

class MastheadBaseWidget extends StatelessWidget {
  final GenericCallBackList genericCallBackList;
  final String? api;

  const MastheadBaseWidget({super.key, required this.api, required this.genericCallBackList});

  @override
  Widget build(BuildContext context) {
    return BlocProvider<MastheadCubit>(
      create: (context) => MastheadCubit(
        mastheadRepository: MastheadRepository(
          networkAssistant: context.read<INetworkAssistant>(),
        ),
      )..getMastheadData(api: api),
      child: MastheadWidgetBuilder(
        data: null,
        genericCallBackList: genericCallBackList,
      ),
    );
  }
}

class MastheadWidgetBuilder extends StatelessWidget {
  const MastheadWidgetBuilder({
    required this.data,
    required this.genericCallBackList,
    Key? key,
  }) : super(key: key);
  final MastheadWidgetData? data;
  final GenericCallBackList? genericCallBackList;

  @override
  Widget build(BuildContext context) {
    return Container(
        height: MediaQuery.of(context).size.height * 0.4, // TODO: Requirement is of removing it
        width: double.infinity,
        decoration: BoxDecoration(
          gradient: LinearGradient(
            begin: Alignment.topLeft,
            end: Alignment.bottomRight,
            colors: [
              data?.mastheadGradientColor1.getHexColor(),
              data?.mastheadGradientColor2.getHexColor()
            ],
          ),
        ),
        child: BlocBuilder<MastheadCubit, MastheadState>(
          buildWhen: (previous, current) {
            if (current is MastheadLoadedState) {
              return true;
            } else {
              return false;
            }
          },
          builder: (context, state) {
            if (state is MastheadLoadedState) {
              return bodyWidgets(state.data, context, genericCallBackList!);
            }
            return emptyContainer;
          },
        ));
  }
}
  • I tried using SliverAppBar instead of SliverToBoxAdapter but it has the same issue where I need to give expandedHeight to it, otherwise it would take up minimum space
  • I tried using Expanded widgets but those are not Sliver specific widgets,
  • I also tried giving boxConstraints to Container with max and min height but it takes max height all the time
0

There are 0 best solutions below