gpt4 book ai didi

listview - Flutter:如何根据Expanded和itemCount自动调整ListView中的高度,宽度,字体大小

转载 作者:行者123 更新时间:2023-12-03 04:46:22 29 4
gpt4 key购买 nike

我有一个这样的页面:

  • 1st Listview:Axis.vertical作为默认
  • 第一列表 View 内的第二列表 View :Axis.horizontalitemCount = 3。为避免错误,我在此
  • 中将 height:50设置为 width:100 Container
    但是,我想找到一种使其在所有屏幕上都能正常显示的方法,特别是在第二个ListView中:
  • Expanded(1:1:1),它适合屏幕的右侧,无法滚动。
  • Width
  • Container将基于Expanded flex自动调整大小。
  • fontSizeTextHeight将根据Container自动调整大小

  • enter image description here

    所以请帮我,这是JSON文件
    [
    {
    "id": 1,
    "continent": "North America",
    "countries": [
    {
    "name": "United States",
    "capital": "Washington, D.C.",
    "language": ["English"]
    },
    {
    "country": "Canada",
    "capital": "Ottawa",
    "language": ["English", "French"]
    },
    {
    "country": "Mexico",
    "capital": "Mexico City",
    "language": ["Spanish"]
    }
    ]
    },
    {
    "id": 2,
    "continent": "Europe",
    "countries": [
    {
    "country": "Germany",
    "capital": "Berlin",
    "language": ["German"]
    },
    {
    "country": "United Kingdom",
    "capital": "London",
    "language": ["English"]
    }
    ]
    },
    {
    "id": 3,
    "continent": "Asia",
    "country": [
    {
    "country": "Singapore",
    "capital": "Singapore",
    "language": ["English","Malay","Mandarin","Tamil"]
    }
    ]
    }
    ]

    这是主要文件
    import 'package:flutter/material.dart';
    import 'model/continent_model.dart';
    import 'services/continent_services.dart';

    class ContinentPage2 extends StatefulWidget {
    ContinentPage2() : super();

    @override
    _ContinentPageState createState() => _ContinentPageState();
    }

    class _ContinentPageState extends State<ContinentPage2> {
    List<Continent> _continent;
    @override
    void initState() {
    super.initState();
    ContinentServices.getContinent().then((continents) {
    setState(() {
    _continent = continents;
    });
    });
    }

    @override
    Widget build(BuildContext context) {
    return Scaffold(
    appBar: AppBar(title: Text('')),
    body: ListView.separated(
    separatorBuilder: (BuildContext context, int index) {
    return SizedBox(height: 10);
    },
    shrinkWrap: true,
    itemCount: null == _continent ? 0 : _continent.length,
    itemBuilder: (context, index) {
    return Column(mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[
    Row(mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: <Widget>[
    Expanded(flex: 1, child: Text(_continent[index].continent)),
    Expanded(
    flex: 2,
    child: Container(
    height: 50,
    child: ListView.separated(
    separatorBuilder: (BuildContext context, int index) {
    return SizedBox(width: 10);
    },
    shrinkWrap: true,
    scrollDirection: Axis.horizontal,
    itemCount: null == _continent ? 0 : _continent[index].country.length,
    itemBuilder: (context, countryIndex) {
    print(_continent[index].country[countryIndex].name);
    return Row(mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[
    Container(
    width: 100,
    child: Column(children: <Widget>[
    Text(
    _continent[index].country[countryIndex].name,
    ),
    Text(_continent[index].country[countryIndex].capital,
    style: TextStyle(
    color: Colors.blue,
    )),
    ]))
    ]);
    })))
    ])
    ]);
    }));
    }
    }

    最佳答案

    import 'dart:math'; //useful to check the longest list of countries 

    class ContinentPage2 extends StatefulWidget {
    ContinentPage2() : super();

    @override
    _ContinentPageState createState() => _ContinentPageState();
    }

    class _ContinentPageState extends State<ContinentPage2> {
    List<Continent> _continent = []; //initialize empty to avoid problem with the table
    int maxLength; //we need to check for the longest list of countries in all the continents

    @override
    void initState() {
    super.initState();

    ContinentServices.getContinent().then((continents) {
    setState(() {
    _continent = continents;
    maxLength = _continent.map((continent) => continent.country.length).reduce(max);
    /*max uses dart:math, I made a list of the length of all the List<countries>
    and then check for the list with the maximum length*/
    });
    });
    }

    @override
    Widget build(BuildContext context) {
    return Scaffold(
    appBar: AppBar(title: Text('')),
    body: SingleChildScrollView(
    child: Table(
    defaultVerticalAlignment: TableCellVerticalAlignment.middle,
    columnWidths: {0: FlexColumnWidth(0.5)}, //accept a map and gives to the index the width I want, in this case the first widget a flex of 0.5, and the others will have the default 1, so it's the same as using expanded with flex: 1 and then flex: 2
    children: [
    for (Continent continent in _continent)
    TableRow(children: [
    TableCell(
    verticalAlignment: TableCellVerticalAlignment.middle,
    child: Text(continent.continent),
    ),
    for (Country country in continent.country)
    Padding(
    padding: const EdgeInsets.symmetric(vertical: 5),
    child: Column(
    mainAxisSize: MainAxisSize.min,
    children: <Widget>[
    Flexible(
    child: FittedBox(
    fit: BoxFit.scaleDown,
    child: Text(country.name),
    ),
    ),
    Flexible(
    child: FittedBox(
    fit: BoxFit.scaleDown,
    child: Text(
    country.capital,
    style: TextStyle(
    color: Colors.blue,
    ),
    textAlign: TextAlign.center,
    )),
    ),
    //OPTION 1 create a String with all the languages as a single text
    if(country.languages.isNotempty)
    Flexible(
    child: MyLanguages(
    lang: country.languages.reduce((prev, curr) => '$prev, $curr')
    )
    ),
    // Option 2 using a for to create multiple text widgets inside the column widget with all the languages per country
    if(country.languages.isNotempty)
    for(String language in country.language)
    Flexible(
    child: Text(language)
    )
    ]),
    ),
    if (continent.country.length < maxLength)
    for (int i = 0; i < maxLength - continent.country.length; i++)
    const SizedBox()
    ])
    ],
    )));
    }
    }


    // Used in Option 1
    class MyLanguages extends StatelessWidget{
    final String languages;

    MyLanguages({String lang, Key key}) : languages = lang.replaceFirst(',', ' and', lang.lastIndexOf(',').clamp(0, double.infinity)), super(key: key);

    @override
    Widget build(BuildContext context){
    return Text(languages);
    }


    }

    对于所有嵌套的行和列,我认为最好的主意是使用Table小部件,它允许用y列制作x行的表,但是只有一个问题,所有行都需要具有相同数量的列(矩形或方形表格)。因此,要解决此问题,我做了一个int maxLength,然后:
    maxLength = _continent.map((continent) => continent.country.length).reduce(max); 

    创建一个具有所有国家/地区长度且具有减少最大值的列表,我检索具有最大长度的列表的值,对下一部分很有用
    if (continent.country.length < maxLength)
    for (int i = 0; i < maxLength - continent.country.length; i++)
    const SizedBox()

    在这里,我检查是否创建了整行,或者该行是否具有少于任何行中最大数量的小部件,然后仅添加虚拟const SizedBox()来欺骗表,使其在每行中具有相同数量的小部件(如果您对此部分发表评论,则会出现错误,因为它需要具有相同数量的列)。
    columnWidths: {0: FlexColumnWidth(0.5)},

    该行与Expanded一起用作flex,它接受map Map,其中键int是每一行中列的索引,在这种情况下,它的值为0,而我给它的flex为0.5,其他保持默认值1.0。如果您想尝试一下,还有其他 TableColumnWidth

    最后,我将国家/地区包裹在垂直5的填充中,使它看起来像您的splitterbuilder SizedBox(height:10),在“列”内部,我使用带有fit.scaleDown的Flexible和FittedBox包裹了文本,从而减小了文本大小填充所有宽度并添加textAlign.center以使文本居中。如果您有一个很大的大文本,它将减小它的大小。如果您不希望这样做,则可以仅保留“文本”小部件并添加maxLines和softWrap
    Text(
    country.capital,
    style: TextStyle(color: Colors.blue),
    textAlign: TextAlign.center,
    maxLines: 2, softWrap: true,
    )

    或者,如果您确实希望通过文本大小进行更多自定义,则可以检查 Auto_Size_Text Package

    fitBox的结果

    With FittedBox

    没有FittedBox和maxLines的结果:2,softwrap:true

    enter image description here

    关于listview - Flutter:如何根据Expanded和itemCount自动调整ListView中的高度,宽度,字体大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62207592/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com