如何在Flutter中配置自定义Listview以及自定义可编辑子ListView?

问题描述

我有一个要实现的功能,我需要配置每个包含TextField和按钮的小部件的自定义列表视图。子窗口小部件包含每个窗口小部件的列表视图,其中包含一个用于输入新课程的TextField。

Overview

以下是功能

  1. 第1步是进入课程的静态字段。
  2. 进入课程后,单击课程字段中的“添加”按钮将添加任何主题的动态窗口小部件的ListView(父listview)。
  3. 加载主题小部件后,单击右侧的添加按钮需要将另一个动态小部件的子级列表视图追加到子主题的父级(子级列表视图)。
  4. 因此,在上图中,2、4是父级列表视图,而3、5需要是子级列表视图

以下是我的代码

import 'package:Flutter/material.dart';

void main() {
  runApp(MaterialApp(debugShowCheckedModeBanner: false,home: NewCourse()));
}

class NewCourse extends StatefulWidget {
  @override
  _NewCourseState createState() => _NewCourseState();
}

class _NewCourseState extends State<NewCourse> {
  bool isTagSelected = false;
  bool isTopicCreationEnabled = false;

  List<NewTopic> newTopicList = [];

  addNewTopic() {
    newTopicList.add(new NewTopic());
    setState(() {});
  }

  enabletopicCreation(String txtTopicName) {
    setState(() {
      if (txtTopicName.length > 0) {
        isTopicCreationEnabled = true;
      } else {
        isTopicCreationEnabled = false;
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    var _createNewTopic;

    if (isTopicCreationEnabled) {
      _createNewTopic = () {
        addNewTopic();
      };
    } else {
      _createNewTopic = null;
    }

    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.blueGrey,title: Text('ALL COURSES'),centerTitle: true,),body: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,children: <Widget>[
          Container(
            color: Colors.blueGrey,child: Center(
              child: Padding(
                padding: EdgeInsets.all(20),child: Text(
                  "NEW COURSE",style: TextStyle(
                    fontSize: 20,fontWeight: FontWeight.bold,fontFamily: 'CodeFont',color: Colors.white,Container(
            padding: EdgeInsets.all(5),decoration: Boxdecoration(
              color: Colors.white,borderRadius: BorderRadius.circular(10),BoxShadow: [
                BoxShadow(
                  color: Colors.grey[400],blurRadius: 20.0,offset: Offset(0,10),],child: Column(
              children: <Widget>[
                Row(
                  mainAxisAlignment: MainAxisAlignment.start,crossAxisAlignment: CrossAxisAlignment.start,children: <Widget>[
                    Expanded(
                      flex: 9,child: Container(
                        padding: EdgeInsets.all(8),margin: EdgeInsets.all(8),child: TextField(
                          onChanged: (text) {
                            enabletopicCreation(text);
                          },decoration: Inputdecoration(
                            border: InputBorder.none,hintText: "Course Name",hintStyle: TextStyle(color: Colors.grey[400]),Expanded(
                      flex: 3,child: FlatButton(
                        onpressed: _createNewTopic,child: Container(
                          padding: EdgeInsets.all(18),child: Icon(
                            Icons.add_Box,color: isTopicCreationEnabled
                                ? Colors.green
                                : Colors.blueGrey,Container(
            child: Expanded(
              child: getAllTopicslistView(),);
  }

  Widget getAllTopicslistView() {
    ListView topicList = new ListView.builder(
        itemCount: newTopicList.length,itemBuilder: (context,index) {
          return new ListTile(
            title: new NewTopic(),);
        });
    return topicList;
  }
}

class NewTopic extends StatefulWidget {
  @override
  _NewTopicState createState() => _NewTopicState();
}

class _NewTopicState extends State<NewTopic> {
  bool isSubTopicCreationEnabled = false;

  List<NewSubTopic> newSubTopicList = [];

  addNewSubTopic() {
    setState(() {
      newSubTopicList.add(new NewSubTopic());
    });
  }

  enableSubTopicCreation(String txtTopicName) {
    setState(
      () {
        if (txtTopicName.length > 0) {
          isSubTopicCreationEnabled = true;
        } else {
          isSubTopicCreationEnabled = false;
        }
      },);
  }

  @override
  Widget build(BuildContext context) {
    var _createNewSubTopic;

    if (isSubTopicCreationEnabled) {
      _createNewSubTopic = () {
        addNewSubTopic();
      };
    } else {
      _createNewSubTopic = null;
    }

    return Column(
      children: [
        Container(
          margin: EdgeInsets.only(top: 20,bottom: 20,left: 10,right: 50),padding: EdgeInsets.all(20),decoration: Boxdecoration(
            color: Colors.white,BoxShadow: [
              BoxShadow(
                color: Colors.grey[400],child: Center(
            child: Column(
              children: <Widget>[
                Row(
                  mainAxisAlignment: MainAxisAlignment.start,child: Container(
                        child: TextField(
                          onChanged: (text) {
                            enableSubTopicCreation(text);
                          },hintText: "Enter the topic",child: FlatButton(
                        onpressed: _createNewSubTopic,child: Container(
                          child: Icon(
                            Icons.add_Box,color: isSubTopicCreationEnabled
                                ? Colors.green
                                : Colors.blueGrey,Row(
                  children: <Widget>[
                    Container(
                      child: Expanded(
                        //child: Text("Hi There!"),child: getAllSubTopicslistView(),);
  }

  Widget getAllSubTopicslistView() {
    ListView subTopicList = new ListView.builder(
       itemCount: newSubTopicList.length,index) {
         return new ListTile(
           title: new NewSubTopic(),);
       },);
     return subTopicList;
  }
}

class NewSubTopic extends StatefulWidget {
  @override
  _NewSubTopicState createState() => _NewSubTopicState();
}

class _NewSubTopicState extends State<NewSubTopic> {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Container(
          margin: EdgeInsets.only(top: 20,left: 50,right: 10),child: Center(
            child: Container(
              child: TextField(
                decoration: Inputdecoration(
                  border: InputBorder.none,hintText: "Enter the sub topic",);
  }
}

这是问题

Error

Assertion Failed: file:///C:/src/Flutter/packages/Flutter/lib/src/rendering/sliver_multi_Box_adaptor.dart:545:12
child.hasSize
is not true

任何帮助/建议将不胜感激。 预先感谢。

解决方法

您只需要收缩包装ListViews:

        ListView topicList = new ListView.builder(
          shrinkWrap: true,itemCount: newTopicList.length,//...
        ListView subTopicList = new ListView.builder(
          shrinkWrap: true,itemCount: newSubTopicList.length,

ListView基本上是一个CustomScrollView,其中包含单个SliverList 其CustomScrollView.slivers属性。

如果滚动视图不收缩包装,则滚动视图将扩展到scrollDirection中允许的最大大小。如果滚动视图在scrollDirection中具有无限制的约束,则收缩包装必须为true。

您可以在ListView中进一步了解shrinkWrapofficial documentaion

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...