简体   繁体   中英

Flutter SingleChildScrollView(Horizontal) within another SingleChildScrollView(Vertical)

How can I make the Flutter SingleChildScrollView(Horizontal) within another SingleChildScrollView(Vertical) code attached here below work?

I am getting the following exception:

Unhandled Exception: Cannot hit test a render box with no size. The hitTest() method was called on this RenderBox: _RenderScrollSemantics#0e053: needs compositing creator: _ScrollSemantics-[GlobalKey#35899] ← Scrollable ← SingleChildScrollView ← ColoredBox ← ConstrainedBox ← Container ← Column ← _SingleChildViewport ← IgnorePointer-[GlobalKey#364d1] ← Semantics ← Listener ← _GestureSemantics ← ⋯ parentData: (can use size) constraints: BoxConstraints(w=414.0, h=896.0) semantic boundary size: MISSING Although this node is not marked as needing layout, its size is not set. A RenderBox object must have an explicit size before it can be hit-tested. Make sure that the RenderBox in question sets its size during layout. #0 RenderBox.hitTest. (package:flutter/src/rendering/box.dart:2386:9) #1 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2401:6) #2 RenderProxyBoxMixin.hitTestChildren (p<…> [VERBOSE-2:ui_dart_state.cc(177)] Unhandled Exception: Cannot hit test a render box with no size. The hitTest() method was called on this RenderBox: _RenderScrollSemantics#0e053: needs compositing creator: _ScrollSemantics-[GlobalKey#35899] ← Scrollable ← SingleChildScrollView ← ColoredBox ← ConstrainedBox ← Container ← Column ← _SingleChildViewport ← IgnorePointer-[GlobalKey#364d1] ← Semantics ← Listener ← _GestureSemantics ← ⋯ parentData: (can use size) constraints: BoxConstraints(w=414.0, h=896.0) semantic boundary size: MISSING Although this node is not marked as needing layout, its size is not set. A RenderBox object must have an explicit size before it can be hit-tested. Make sure that the RenderBox in question sets its size during layout. #0 RenderBox.hitTest. (package:flutter/src/rendering/b ox.dart:2386:9) #1 RenderBox.hitTest (package:flutter/src/rendering/box.dart:2401:6) #2 RenderProxyBoxMixin.hitTestChildren (p<…>

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

void main() => runApp(
      MaterialApp(
        home: HomeScreen(),
      ),
    );

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    SizeConfig().init(context);

    return Scaffold(
      appBar: AppBar(
        title: Text('Grid Demo'),
      ),
      body: SingleChildScrollView(
        scrollDirection: Axis.vertical,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            Container(
              width: SizeConfig.screenWidth,
              height: SizeConfig.screenHeight,
              color: Colors.grey[200],
              child: SingleChildScrollView(
                scrollDirection: Axis.horizontal,
                child: Grid(),
              ),
            ),
            SizedBox(
              height: 50,
            ),
            Container(color: Colors.grey, height: 200),
          ],
        ),
      ),
    );
  }
}

class Grid extends StatelessWidget {
  List<Positioned> getUnits() {
    double _unitRadius = 50;
    List<Positioned> _units = [];
    double _leftCoordinate = 0;
    double _bottomCoordinate = 0;
    double _margin = 5;
    double _stepFromLeft = _unitRadius + _margin;
    double _stepFromBottom = _unitRadius + _margin;

    int _maxColumns = 10;
    int _maxRows = 10;

    for (int i = 0; i < _maxRows; i++) {
      for (int j = 0; j < _maxColumns; j++) {
        _units.add(Positioned(
            bottom: _bottomCoordinate,
            left: _leftCoordinate,
            child: Container(
              width: _unitRadius,
              height: _unitRadius,
              decoration: BoxDecoration(
                color: Colors.green,
              ),
              child: Center(child: Text('$i $j')),
            )));
        _leftCoordinate += _stepFromLeft;
      }
      _leftCoordinate = 0;
      _bottomCoordinate += _stepFromBottom;
    }

    return _units;
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: getUnits(),
    );
  }
}

class SizeConfig {
  static MediaQueryData _mediaQueryData;
  static double screenWidth;
  static double screenHeight;
  static double blockSizeHorizontal;
  static double blockSizeVertical;
  static double _safeAreaHorizontal;
  static double _safeAreaVertical;
  static double safeBlockHorizontal;
  static double safeBlockVertical;

  void init(BuildContext context) {
    _mediaQueryData = MediaQuery.of(context);
    screenWidth = _mediaQueryData.size.width;
    screenHeight = _mediaQueryData.size.height;
    blockSizeHorizontal = screenWidth;
    blockSizeVertical = screenHeight;
    _safeAreaHorizontal =
        _mediaQueryData.padding.left + _mediaQueryData.padding.right;
    _safeAreaVertical =
        _mediaQueryData.padding.top + _mediaQueryData.padding.bottom;

    safeBlockHorizontal = (screenWidth - _safeAreaHorizontal);
    safeBlockVertical = (screenHeight - _safeAreaVertical);
  }
}

Try to put the vertical singlechildscrollview in a container, and set the width and height of this container to screen width and height. On the other hand it's more appropriate if you use ListView for horizontal scrolling, or ListView.builder if your items are of same types

ListView(
    scrollDirection: Axis.horizontal,
    shrinkWrap:      true,
    children: <Widget>[
        //your widget items here
    ],
),

Here Your SingleChildScrollView items will scroll in vertically and ListView.builder items will draw items horizontally, (by default), in case of list view builder you need to fix a specific/dynamic height to avoid errors.

SingleChildScrollView(
      child: Container(
          height: 100,
             child: ListView.builder(
                  itemBuilder: ...),
              ),
            )

& in your code, use:

   Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      mainAxisSize: MainAxisSize.max,

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM