如何使用Flutter制作一个Expandable ListView,如下面的屏幕截图所示?
Expandable ListView
我想制作一个可滚动的列表视图,ExpansionTiles展开时会显示一个不可滚动的列表视图。
ExpansionTiles
我尝试实现ExpansionTiles内部的列表视图,并使用嵌套了另一个列表视图listView.builder(...)。但是,当我展开 ExpansionTile列表视图时,它没有出现……
listView.builder(...)
有没有办法在Flutter中获得类似的输出?
编辑:我的源代码:
import 'package:flutter/material.dart'; void main() => runApp( new MaterialApp( home: new MyApp(), ) ); var data = { "01/01/2018": [ ["CocaCola", "\$ 5"], ["Dominos Pizza", "\$ 50"], ], "04/01/2018": [ ["Appy Fizz", "\$ 10"], ["Galaxy S9+", "\$ 700"], ["Apple iPhone X", "\$ 999"], ], }; List<String> dataKeys = data.keys.toList(); String getFullDate(String date) { List<String> dateSplit = date.split('/'); List<String> months = ["Jan", "Feb", "Mar", "Apr", "May", "June", "July", "Aug", "Sep", "Oct", "Nov", "Dec"]; return "${dateSplit[0]} ${months[int.parse(dateSplit[1]) - 1]} ${dateSplit[2]}"; } class MyApp extends StatefulWidget { @override _MyAppState createState() => new _MyAppState(); } class _MyAppState extends State<MyApp> { List<Widget> _buildList(int keyIndex) { List<Widget> list = []; for (int i = 0; i < data[dataKeys[keyIndex]].length; i++) { list.add( new Row( children: <Widget>[ new CircleAvatar( child: new Icon(Icons.verified_user), radius: 20.0, ), new Text(data[dataKeys[keyIndex]][i][0]) ], ) ); } return list; } @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( title: new Text("Expense Monitor"), ), body: new Container ( child: new ListView.builder( itemCount: dataKeys.length, itemBuilder: (BuildContext context, int keyIndex) { return new Card( child: new ExpansionTile( title: new Text(getFullDate(dataKeys[keyIndex])), children: <Widget>[ new Column( children: _buildList(keyIndex) ) ] ), ); } ) ) ); } }
Error as shown in Console:
I/flutter (12945): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════ I/flutter (12945): The following assertion was thrown during performResize(): I/flutter (12945): Vertical viewport was given unbounded height. I/flutter (12945): Viewports expand in the scrolling direction to fill their container.In this case, a vertical I/flutter (12945): viewport was given an unlimited amount of vertical space in which to expand. This situation I/flutter (12945): typically happens when a scrollable widget is nested inside another scrollable widget. I/flutter (12945): If this widget is always nested in a scrollable widget there is no need to use a viewport because I/flutter (12945): there will always be enough vertical space for the children. In this case, consider using a Column I/flutter (12945): instead. Otherwise, consider using the "shrinkWrap" property (or a ShrinkWrappingViewport) to size I/flutter (12945): the height of the viewport to the sum of the heights of its children. I/flutter (12945): When the exception was thrown, this was the stack: I/flutter (12945): #0 RenderViewport.performResize.<anonymous closure> (package:flutter/src/rendering/viewport.dart:944:15) I/flutter (12945): #1 RenderViewport.performResize (package:flutter/src/rendering/viewport.dart:997:6) I/flutter (12945): #2 RenderObject.layout (package:flutter/src/rendering/object.dart:1555:9) I/flutter (12945): #3 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:109:13) ...... I/flutter (12945): ════════════════════════════════════════════════════════════════════════════════════════════════════ I/flutter (12945): Another exception was thrown: RenderBox was not laid out: RenderViewport#df29c NEEDS-LAYOUT NEEDS-PAINT
Try this:
import 'package:flutter/material.dart'; void main() => runApp(new MaterialApp(home: new MyApp(), debugShowCheckedModeBanner: false,),); class MyApp extends StatefulWidget { @override _MyAppState createState() => new _MyAppState(); } class _MyAppState extends State<MyApp> { @override Widget build(BuildContext context) { return new Scaffold( body: new ListView.builder( itemCount: vehicles.length, itemBuilder: (context, i) { return new ExpansionTile( title: new Text(vehicles[i].title, style: new TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold, fontStyle: FontStyle.italic),), children: <Widget>[ new Column( children: _buildExpandableContent(vehicles[i]), ), ], ); }, ), ); } _buildExpandableContent(Vehicle vehicle) { List<Widget> columnContent = []; for (String content in vehicle.contents) columnContent.add( new ListTile( title: new Text(content, style: new TextStyle(fontSize: 18.0),), leading: new Icon(vehicle.icon), ), ); return columnContent; } } class Vehicle { final String title; List<String> contents = []; final IconData icon; Vehicle(this.title, this.contents, this.icon); } List<Vehicle> vehicles = [ new Vehicle( 'Bike', ['Vehicle no. 1', 'Vehicle no. 2', 'Vehicle no. 7', 'Vehicle no. 10'], Icons.motorcycle, ), new Vehicle( 'Cars', ['Vehicle no. 3', 'Vehicle no. 4', 'Vehicle no. 6'], Icons.directions_car, ), ];