Flutter中DataTable添加列后RenderFlex右侧溢出的解决方法
Flutter DataTable添加列后溢出问题解决
问题说明
给Flutter应用的DataTable新增列后,出现错误提示:A RenderFlex overflowed by 71 pixels on the right.,需要让表格列适配屏幕尺寸,解决溢出问题。
错误截图:
原相关代码:
// For CircularProgressIndicator. bool visible = false; String? dropdownValue = 'Hoy'; @override Widget build(BuildContext context) { return Scaffold( appBar: new AppBar( backgroundColor: Colors.black87, leading: BackButton( color: Colors.white, onPressed: () { Navigator.push(context, MaterialPageRoute(builder: (context) => HomePage(0, 0))); }, ), title: new Text("Planilla de horarios"), ), body: (!visible) ? Container( color: Colors.white, height: MediaQuery.of(context).size.height, child: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.max, children: <Widget>[ Container( color: Colors.grey, child: Row(children: <Widget>[ FutureBuilder<String>( future: globals.SharedPreferencesHelper .getDataFilterDebt(), builder: (context, snapshot) { if (snapshot.hasData) { return Expanded( child: Row( children: <Widget>[ Expanded( flex: 2, child: DropdownButton<String>( value: dropdownValue, icon: Icon(Icons.arrow_downward), iconSize: 24, iconEnabledColor: Colors.white, elevation: 16, style: TextStyle(color: Colors.black), underline: Container( height: 0, color: Colors.black, ), onChanged: (String? newValue) { setState(() { dropdownValue = newValue; }); }, items: <String>['Hoy', 'Mañana'] .map<DropdownMenuItem<String>>( (String value) { return DropdownMenuItem<String>( value: value, child: Text(value), ); }).toList(), ), ), Container( margin: const EdgeInsets.only(right: 10.0), color: Colors.grey, child: new Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ FlatButton( child: Text("Buscar"), color: Color(0xFF1F1F1F), textColor: Colors.white, padding: EdgeInsets.only( left: 2, right: 2, top: 2, bottom: 2), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular( 5)), onPressed: () { obtenerDetallesTecnicasImplantes( dropdownValue.toString()); setState(() {}); }, ), ]), ), ], ), ); } else if (snapshot.hasError) { return Image.asset("images/fundo_login.jpg"); } else { return Container( margin: EdgeInsets.only(top: 18), child: Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Visibility( child: Container( margin: EdgeInsets.only(bottom: 17.5), child: CircularProgressIndicator( valueColor: AlwaysStoppedAnimation<Color>( Colors.black), ), height: 20, width: 20, )), ], ), ); } }), ]), ), DataTable( columns: [ DataColumn(label: Text('Hora')), DataColumn(label: Text('Sector')), DataColumn(label: Text('Agente')), DataColumn(label: Text('Agente de cobertura')), ], rows: scheduleList // Loops through dataColumnText, each iteration assigning the value to element .map( ((element) => DataRow( cells: <DataCell>[ DataCell(Text(element![ "ingreso"])), //Extracting from Map element the value DataCell( Text(element["sector_nombre"])), DataCell(Text(element["apellidos"] + " " + element["nombres"])), DataCell(Text(element["agente_cobertura_det"])), ], )), ) .toList(), ), ], ), ), ) : pageLoadingView(), ); } Widget pageLoadingView() { return Container( margin: EdgeInsets.only(top: 300), child: Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Visibility( visible: visible, child: Container( margin: EdgeInsets.only(bottom: 30), child: CircularProgressIndicator( valueColor: AlwaysStoppedAnimation<Color>(Colors.black), ))), ], ), ); } Color hexToColor(String code) { return new Color(int.parse(code.substring(1, 7), radix: 16) + 0xFF000000); }
解决方法
核心思路
DataTable本身不支持横向滚动,且默认列宽由内容决定,当列数/内容宽度超过屏幕时就会溢出。可以通过以下两种方式组合解决:
- 添加横向滚动:用
SingleChildScrollView包裹DataTable,设置滚动方向为水平,让用户可以左右滑动查看全列。 - 内容自适应:给列标题和单元格内容包裹
Expanded/Flexible,开启文本自动换行,让内容根据可用空间调整。
修改后的关键代码
替换原代码中的DataTable部分为以下内容:
// 新增横向滚动组件 SingleChildScrollView( scrollDirection: Axis.horizontal, child: DataTable( columns: [ DataColumn(label: Expanded(child: Text('Hora', softWrap: true))), DataColumn(label: Expanded(child: Text('Sector', softWrap: true))), DataColumn(label: Expanded(child: Text('Agente', softWrap: true))), DataColumn(label: Expanded(child: Text('Agente de cobertura', softWrap: true))), ], rows: scheduleList .map(((element) => DataRow( cells: <DataCell>[ DataCell(Expanded(child: Text(element!["ingreso"], softWrap: true))), DataCell(Expanded(child: Text(element["sector_nombre"], softWrap: true))), DataCell(Expanded(child: Text(element["apellidos"] + " " + element["nombres"], softWrap: true))), DataCell(Expanded(child: Text(element["agente_cobertura_det"], softWrap: true))), ], ))) .toList(), ), )
如果需要按比例分配列宽,可以改用Flexible并设置flex属性:
DataColumn(label: Flexible(flex: 1, child: Text('Hora', softWrap: true))), DataColumn(label: Flexible(flex: 2, child: Text('Sector', softWrap: true))), // flex值越大,列宽度占比越高
内容的提问来源于stack exchange,提问作者LUIS TISCORNIA
相关产品推荐
相关产品推荐

