Flutter - 垂直视口被赋予无限高度

Flutter - Vertical viewport was given unbounded height

我想在显示的图像下写下可用的设备,如下所示:

如果我删除图像部分,我只会得到可用的设备,但我需要在 BLE 设备上方添加图像。

但是如果我 运行 我的代码:

Performing hot reload...
Syncing files to device Redmi Note 8 Pro...

════════ Exception caught by rendering library ═════════════════════════════════════════════════════
The following assertion was thrown during performResize():
Vertical viewport was given unbounded height.

Viewports expand in the scrolling direction to fill their container. In this case, a vertical viewport was given an unlimited amount of vertical space in which to expand. This situation typically happens when a scrollable widget is nested inside another scrollable widget.

If this widget is always nested in a scrollable widget there is no need to use a viewport because there will always be enough vertical space for the children. In this case, consider using a Column instead. Otherwise, consider using the "shrinkWrap" property (or a ShrinkWrappingViewport) to size the height of the viewport to the sum of the heights of its children.

The relevant error-causing widget was: 
  ListView file:///F:/epicare/lib/BluetoothScanningDevices.dart:113:12
When the exception was thrown, this was the stack: 
#0      RenderViewport.computeDryLayout.<anonymous closure> (package:flutter/src/rendering/viewport.dart:1365:15)
#1      RenderViewport.computeDryLayout (package:flutter/src/rendering/viewport.dart:1426:6)
#2      RenderBox.performResize (package:flutter/src/rendering/box.dart:2342:12)
#3      RenderObject.layout (package:flutter/src/rendering/object.dart:1763:9)
#4      RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:118:14)
...
The following RenderObject was being processed when the exception was fired: RenderViewport#6aa27 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
...  needs compositing
...  parentData: <none> (can use size)
...  constraints: BoxConstraints(0.0<=w<=392.7, 0.0<=h<=Infinity)
...  size: MISSING
...  axisDirection: down
...  crossAxisDirection: right
...  offset: ScrollPositionWithSingleContext#5f4da(offset: 0.0, range: null..null, viewport: null, ScrollableState, AlwaysScrollableScrollPhysics -> ClampingScrollPhysics -> RangeMaintainingScrollPhysics, IdleScrollActivity#9b3a7, ScrollDirection.idle)
...  anchor: 0.0
RenderObject: RenderViewport#6aa27 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
  needs compositing
  parentData: <none> (can use size)
  constraints: BoxConstraints(0.0<=w<=392.7, 0.0<=h<=Infinity)
  size: MISSING
  axisDirection: down
  crossAxisDirection: right
  offset: ScrollPositionWithSingleContext#5f4da(offset: 0.0, range: null..null, viewport: null, ScrollableState, AlwaysScrollableScrollPhysics -> ClampingScrollPhysics -> RangeMaintainingScrollPhysics, IdleScrollActivity#9b3a7, ScrollDirection.idle)
  anchor: 0.0
...  center child: RenderSliverPadding#47e11 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
...    parentData: paintOffset=Offset(0.0, 0.0)
...    constraints: MISSING
...    geometry: null
...    padding: EdgeInsets.all(8.0)
...    textDirection: ltr
...    child: RenderSliverList#673c8 NEEDS-LAYOUT NEEDS-PAINT
...      parentData: paintOffset=Offset(0.0, 0.0)
...      constraints: MISSING
...      geometry: null
...      no children current live
════════════════════════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════════════════════════
RenderBox was not laid out: RenderViewport#6aa27 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1940 pos 12: 'hasSize'
The relevant error-causing widget was: 
  ListView file:///F:/epicare/lib/BluetoothScanningDevices.dart:113:12
════════════════════════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════════════════════════
RenderBox was not laid out: RenderViewport#6aa27 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1940 pos 12: 'hasSize'
The relevant error-causing widget was: 
  ListView file:///F:/epicare/lib/BluetoothScanningDevices.dart:113:12
════════════════════════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════════════════════════
RenderBox was not laid out: RenderIgnorePointer#d974c relayoutBoundary=up20 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1940 pos 12: 'hasSize'
The relevant error-causing widget was: 
  ListView file:///F:/epicare/lib/BluetoothScanningDevices.dart:113:12
════════════════════════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════════════════════════
RenderBox was not laid out: RenderSemanticsAnnotations#6e459 relayoutBoundary=up19 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1940 pos 12: 'hasSize'
The relevant error-causing widget was: 
  ListView file:///F:/epicare/lib/BluetoothScanningDevices.dart:113:12
════════════════════════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════════════════════════
RenderBox was not laid out: RenderPointerListener#0c15f relayoutBoundary=up18 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1940 pos 12: 'hasSize'
The relevant error-causing widget was: 
  ListView file:///F:/epicare/lib/BluetoothScanningDevices.dart:113:12
═════════════════════════════════════════════════════════════════════════════════════════════════

我的代码是:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'BluetoothConnectBand.dart';
import 'BluetoothConnectedSuccess.dart';
import 'package:flutter_blue/flutter_blue.dart';


class BluetoothScanningDevices extends StatefulWidget {
  @override
  _BluetoothScanningDevicesState createState() => _BluetoothScanningDevicesState();
}

class _BluetoothScanningDevicesState extends State<BluetoothScanningDevices> {
  FlutterBlue flutterBlueInstance  = FlutterBlue.instance;
  final List<BluetoothDevice> devicesList = new List<BluetoothDevice>();
  _addDeviceTolist(final BluetoothDevice device) {
    if (!devicesList.contains(device)) {
      setState(() {
        devicesList.add(device);
      });
    }
  }
  @override
  void initState() {
    super.initState();
    FlutterBlue.instance.connectedDevices
        .asStream()
        .listen((List<BluetoothDevice> devices) {
      for (BluetoothDevice device in devices) {
        _addDeviceTolist(device);
      }
    });
    FlutterBlue.instance.scanResults.listen((List<ScanResult> results) {
      for (ScanResult result in results) {
        _addDeviceTolist(result.device);
      }
    });
    FlutterBlue.instance.startScan();
  }
  ListView _buildListViewOfDevices() {
    Size size = MediaQuery.of(context).size;
    List<Container> containers = new List<Container>();
    for (BluetoothDevice device in devicesList) {
      containers.add(
        Container(
          width: size.width,
          child: RaisedButton(
            padding: EdgeInsets.symmetric(vertical:10.0, horizontal: 15.0),
            elevation: 5.0,
            color: Colors.white,
            onPressed: (){
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context){
                    return BluetoothConnectedSuccess();
                  },
                ),
              );
            },
            child:Column(
              children: [
                Align(
                  alignment: Alignment.centerLeft,
                  child: Text(
                    device.name == '' ? '(Unknown Device)' : device.name,
                    style: TextStyle(
                      fontSize: 15.0,
                      color: Colors.black,
                      fontWeight: FontWeight.w600,
                      fontFamily: 'Montserrat',
                    ),
                  ),
                ),
                Align(
                  alignment: Alignment.centerLeft,
                  child: Text(
                      device.id.toString(),
                      style: TextStyle(
                        fontSize: 13.0,
                        color: Colors.black,
                        fontWeight: FontWeight.w500,
                        fontFamily: 'Montserrat',
                      )
                  ),
                ),
              ],
            ),
          ),
        ),
      );
    }
    return ListView(
      padding: const EdgeInsets.all(8),
      children: <Widget>[
        ...containers,
      ],
    );
  }
  @override
  Widget build(BuildContext context) {
    Size size = MediaQuery.of(context).size;
    return Scaffold(
      appBar: AppBar(
        backgroundColor: const Color(0xffE5E0A1),
        elevation: 0,
        centerTitle: true,
        title: Text("Connect Band",
          style: TextStyle(
            fontSize: 15.0,
            color: Colors.black,
            fontFamily: 'Montserrat',
            fontWeight: FontWeight.normal,
          ),
        ) ,
        leading: IconButton(icon: Icon(Icons.arrow_back,color: Colors.black,),onPressed: (){
          Navigator.push(
            context,
            MaterialPageRoute(builder: (context){
              return BluetoothConnectBand();
            },
            ),
          );
        },
        ),
        actions: [
          Padding(
            padding: EdgeInsets.only(right: 5.0),
            child: FlatButton(
              onPressed: () {
              },
              child: Text(
                "Search",
                style: TextStyle(
                  fontSize: 15.0,
                  color: Colors.black,
                  fontWeight: FontWeight.normal,
                  fontFamily: 'Montserrat',
                ),
              ),
            ),
          )
        ],
      ),

      body: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Container(
              height: size.height*0.4,
              width: size.width,
              color: const Color(0xffE5E0A1),
              child: Image.asset('assets/images/bluetooth.png',)
          ),
          Container(
            width: size.width,
            padding: EdgeInsets.symmetric(vertical: 20),
            child: Text(
              "Scanning Available Devices...",
              style: TextStyle(
                fontSize: 15.0,
                color: Colors.black,
                fontWeight: FontWeight.w400,
                fontFamily: 'Montserrat',
              ),
              textAlign: TextAlign.center,
            ),
          ),
          SingleChildScrollView(
            child: _buildListViewOfDevices(),
          )

        ],
      ),
    );
  }
}

请帮助我,告诉我如何在图片下方写下可用的 BLE 设备,如附图所示 P.S: 我是 Flutter 新手

如日志所示,错误在第 113 行。我猜这是由 _buildListViewOfDevices 中的 ListView 引起的。

首先,不需要用SingleChildScrollView包裹这个ListView,列表视图已经可以滚动了。

其次,将 ListView 换成 Expanded。这是告诉 ListView 只需占用 Column 小部件中所有剩余的屏幕 space。

_buildListViewOfDevices() 函数中 ListViewshrinkWrap 属性 设置为 true。这可能有用。

您也可以删除 ListView 之前的 SingleChildScrollView。不用了,ListView已经可以滚动了