首页 > 解决方案 > Flutter:当我使用 LIstView 时,RenderBox 没有布局

问题描述

我正在尝试创建一个 ListView,但是当我构建列表时出现错误。我已经阅读了这篇文章: Flutter:RenderBox 没有布局

我试图这样做,但我仍然得到同样的错误

这是错误:

RenderBox was not laid out: RenderFlex#19d12 relayoutBoundary=up22 NEEDS-PAINT
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1785 pos 12: 'hasSize'

这是代码:

import 'package:flutter/material.dart';
import 'package:notenverwaltung/UI/Fach/fach_page.dart';
import 'package:notenverwaltung/models/global.dart';
import 'dart:async';
import 'package:http/http.dart' as http;
import 'dart:convert';

class SemesterModel {
  SemesterModel({this.id, this.name, this.durchschnitt, this.jahr, this.notiz});
  final int id;
  String name;
  double durchschnitt;
  String jahr;
  String notiz;
}

class Semester extends StatelessWidget {
  //SemesterModel model;
  static const _semesterUrl = 'http://10.0.2.2:8888/semester';
  static final _headers = {'Content-Type': 'application/json'};

  const Semester({
    Key key,
  }) : super(key: key);

  Future<List<SemesterModel>> getSemester() async {
    final response = await http.get(_semesterUrl);
    //print(response.body);
    if (response.statusCode == 200) {
      List responseJson = json.decode(response.body.toString());
      List<SemesterModel> semesterList = createSemesterList(responseJson);
      print(semesterList);
      for (int i = 0; i < semesterList.length; i++) {
        print(semesterList[i].id);
        print(semesterList[i].name);
        print(semesterList[i].durchschnitt);
        print(semesterList[i].jahr);
        print(semesterList[i].notiz);
      }

      return semesterList;
    } else {
      throw Exception('Failed to load note');
    }
  }

  List<SemesterModel> createSemesterList(List data) {
    List<SemesterModel> list = new List();
    //print(data);

    for (int i = 0; i < data.length; i++) {
      int id = data[i]["id"];
      String name = data[i]["name"];
      double durchschnitt = data[i]["durchschnitt"];
      String jahr = data[i]["jahr"];
      String notiz = data[i]["notiz"];
      SemesterModel semesterObject = new SemesterModel(
          id: id,
          name: name,
          durchschnitt: durchschnitt,
          jahr: jahr,
          notiz: notiz);
      list.add(semesterObject);
    }
    return list;
  }

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
        scrollDirection: Axis.horizontal,
        child: new FutureBuilder(
          future: getSemester(),
          builder: (context, snapshot) {
            if (snapshot.data == null) {
              return Container(
                child: Container(
                  child: Text("Loading..."),
                ),
              );
            } else if (snapshot.hasData) {
              return Column(children: <Widget>[
                Expanded(
                  child: ListView.builder(
                      shrinkWrap: true,
                      itemCount: snapshot.data.length,
                      itemBuilder: (context, index) {
                        var semester = snapshot.data[index];
                        return SemesterCard(
                            semesterName: semester.name,
                            year: semester.jahr,
                            semesterAvg: semester.name,
                            press: () {
                              Navigator.push(
                                context,
                                MaterialPageRoute(
                                  //DetailsScreen()
                                  builder: (context) => FachScreen(),
                                ),
                              );
                            });
                      }),
                )
              ]);
            } else {
              return new CircularProgressIndicator();
            }
          },
       ));
}

这是 SemesterCard 类:

class SemesterCard extends StatelessWidget {
  const SemesterCard({
    Key key,
    this.semesterName,
    this.year,
    this.semesterAvg,
    this.press,
  }) : super(key: key);

  final String semesterName, year;
  final double semesterAvg;
  final Function press;

  @override
  Widget build(BuildContext context) {
    Size size = MediaQuery.of(context).size;
    return Container(
      margin: EdgeInsets.only(
        left: kDefaultPadding,
        top: kDefaultPadding / 2,
        bottom: kDefaultPadding / 2,
      ),
      width: size.width * 0.9,
      child: Column(
        children: <Widget>[
          GestureDetector(
            onTap: press,
            child: Container(
              padding: EdgeInsets.all(kDefaultPadding / 2),
              decoration: BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.only(
                  bottomLeft: Radius.circular(10),
                  bottomRight: Radius.circular(10),
                  topLeft: Radius.circular(10),
                  topRight: Radius.circular(10),
                ),
                boxShadow: [
                  BoxShadow(
                    offset: Offset(0, 10),
                    blurRadius: 50,
                    color: kPrimaryColor.withOpacity(0.23),
                  ),
                ],
              ),
              child: Row(
                children: <Widget>[
                  RichText(
                    text: TextSpan(
                      children: [
                        TextSpan(
                            text: "$semesterName\n".toUpperCase(),
                            style: Theme.of(context).textTheme.button),
                        TextSpan(
                          text: "$year".toUpperCase(),
                          style: TextStyle(
                            color: kPrimaryColor.withOpacity(0.5),
                          ),
                        ),
                      ],
                    ),
                  ),
                  Spacer(),
                  Text('$semesterAvg',
                      style: Theme.of(context).textTheme.button.copyWith(
                            color: ((this.semesterAvg < 4.0)
                                ? kTextRed
                                : (this.semesterAvg < 5.0 &&
                                        this.semesterAvg > 4.0)
                                    ? kTextYellow
                                    : kTextGreen),
                          ))
                ],
              ),
            ),
          )
        ],
      ),
    );
  }
}

我对这个扩展功能有很多问题。请帮忙!!!

标签: flutterhttpdartfrontend

解决方案


关于您的代码的注意事项。

  1. 当使用 SingleChildScrollView 作为水平轴时,您需要为其提供一个固定的高度,水平项目将沿着该高度移动。这可以通过使用容器包装 SingleChildScrollView 并设置“hieght”属性来完成。

  2. 如果 Flex 小部件(列或行)位于 Scrollable(例如 SingleChildScrollView)内,则不要在 Flex 小部件(列或行)中使用灵活或展开。

  3. 您不需要 Column 包装 ListView 构建器,因为您想在水平轴上滚动。并将 ListView 构建器的轴设置为水平。如果您想控制 SingleChildScrollView 的滚动,请将物理设置为 NeverScrollablePhysics,否则您应该删除 SingleChildScrollView 并仅使用 ListView 构建器,该构建器单独包装在具有设定高度的容器中。


推荐阅读