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

问题描述

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

enter image description here

如果我删除图像部分,我只会得到可用的设备,但我需要在 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,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,fontWeight: FontWeight.w500,)
                  ),],);
    }
    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,fontWeight: FontWeight.normal,leading: IconButton(icon: Icon(Icons.arrow_back,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,)
        ],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,fontWeight: FontWeight.w400,textAlign: TextAlign.center,SingleChildScrollView(
            child: _buildListViewOfDevices(),)

        ],);
  }
}

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

解决方法

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

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

第二,用 ListView 包裹 Expanded。这告诉 ListView 只需占用 Column 小部件中所有剩余的屏幕空间。

,

shrinkWrap 函数中 ListView_buildListViewOfDevices() 属性设置为 true。这可能会奏效。

您也可以在 SingleChildScrollView 之前删除 ListView。不需要它,ListView 已经可以滚动了。