如何使用DrawerHeader和ListView.builder

时间:2020-04-12 15:57:40

标签: for-loop flutter dart widget for-in-loop

编辑2: 一整天都在此之后。我终于设法与ListView.builder一起工作,最初的问题不再是问题... :)。但是现在出现了一个更具体的问题。 显然,我面临的所有麻烦都是由于在同一抽屉上同时使用了DrawerHeader和ListView.builder。我的所有尝试都导致许多不同类型的错误。有人可以告诉我如何在下面的代码中正确插入抽屉标头吗?

import 'package:flutter/material.dart';

class MyHomePage extends StatelessWidget {

  List<String> items = [
    'Alimentação', 'Artigos para o lar', 'Beleza', 'Carros',
    'Computadores', 'Consertos', 'Construção', 'Ensino',
    'Esporte', 'Pet', 'Presentes', 'Religião',
    'Saúde', 'Serviços Gráficos', 'Serviços para o lar', 'Serviços profissionais',
  ];

  List<IconData> icones = [
    Icons.play_arrow, Icons.list, Icons.create_new_folder, Icons.add_alarm,
    Icons.insert_comment, Icons.drag_handle, Icons.ac_unit, Icons.adjust,
    Icons.airline_seat_recline_extra, Icons.forum, Icons.gamepad, Icons.hd,
    Icons.format_align_justify, Icons.keyboard, Icons.list, Icons.mail,
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(
          'Teste de app',
        ),
      ),
      drawer: Drawer(
        child: ListView.builder(
          itemCount: items.length,
          itemBuilder: (context, i){
            return ListTile(
              title: Text(items[i]),
              leading: Icon(icones[i]),
              trailing: Icon(Icons.chevron_right),
              onTap: (){
                Navigator.pop(context);
              },
            );
          },
        ),
      ),
      body: Container(
        child: Text(
            'Texto'
        ),
      ),
    );
  } 
}

编辑1: 在获得第一个帮助之后,我设法使用ScrollView.builder放置了列表,但是菜单不再滚动。经过一些研究,我将ScrollView包裹在具有固定高度的SizedBox中,并且可以正常工作。唯一的问题是固定高度。我确定这不是最合适的方法,但是当我将固定高度更改为double.infinity时,我得到一个错误:

在performLayout()期间引发了以下断言: BoxConstraints强制将高度设为无限。

你们能告诉我我做错了吗?

//----------------TEST--------------------------------
class TestDrawer extends StatelessWidget {

  @override
  Widget build(BuildContext context) {

    return Column(
      children: <Widget>[
        SizedBox(
          height: double.infinity,
          child: ListView.builder(
            itemCount: kCategorias.length,
            itemBuilder: (_, int index){
              return ListTile(
                title: Text(
                  kCategorias[index],
                ),
                leading: Icon(kIcones[index]),
                trailing: Icon(Icons.play_arrow),
                onTap: (){
                  Navigator.pop(context);
                },
              );
            },
          ),
        ),
      ],
    );
  }
}

原始帖子:

为了进行情境化,我开始研究Flutter,最后我感到有足够的信心去“玩”我的第一个项目。这是与交付合作的公司的instagram帐户的简单目录。如果可以完成,我将在商店中启动该应用程序,以帮助本地公司应对流行病和社会隔离。

ATM我正在处理应用程序的抽屉,并且一切工作都很好。但是我被卡住了。我想创建一个类别菜单。菜单项是ListTiles。我有两个列表来管理此菜单。一个列出类别名称的列表,另一个列出各个类别图标的列表。以后我需要第三个列表,其中包含每个菜单项的链接。

好吧,我要做的就是迭代每个ListTile项中的每个列表。类别列表有效100%。当我尝试迭代同一ListTile小部件内的第二个列表时,问题开始了。

我想到解决此问题的第一件事当然是创建一个for循环,并在其中使用尽可能多的具有相同索引的列表。我在DartPad中测试了这种可能性,并且效果很好!它完全按照我想要的方式返回。问题在于,为了正常工作,我需要使用for ...循环,并且当我将相同的想法转移到我的应用程序代码中时,它仅适用于单行结构(无花括号)。一旦放入大括号,它就会返回错误(元素类型'Set<ListTile>'无法分配给列表类型'Widget'。)但是,如果我使用单行结构,不能重复多个列表。在我看来,唯一可行的方法是迭代2个或更多列表,使用大括号形式。

我不知道我是否足够清楚,但是我该如何解决这个问题?如何使用for循环在单个Widget(在我的情况下为ListTile())中迭代2个或更多列表?

下面,我将附上我遇到麻烦的类的源代码。 如果您想查看整个项目并测试here是github上项目回购的链接。

提前谢谢!

//Builds a Drawer item using ListTile()
class BuildDrawerTile extends StatelessWidget {

List<String> list;
BuildDrawerTile({@required this.list});

@override

Widget build(BuildContext context) {

return Column(
  mainAxisAlignment: MainAxisAlignment.center,
  children: <Widget>[
    for(String item in list ) ListTile( //HERE EVERYTHING WORKS WELL AS I'M NOT USING CURLY BRACKETS
      title: Text(
        item,
        style: GoogleFonts.quicksand(
          textStyle: TextStyle(
            color: Color(0xFF808080),
            fontWeight: FontWeight.w300,
          ),
        ),
      ),
      leading: Icon(Icons.play_arrow), //HERE I NEEDED TO ITERATE SPECIFIC ICONS FOR EACH ITEM
      trailing: Icon(Icons.play_arrow),
      onTap: (){
        Navigator.pop(context); //IN THE FUTURE HERE I'LL ITERATE A THIRD LIST WITH THE DESTINATIONS
      },
    ),
  ],
);
}
}

2 个答案:

答案 0 :(得分:1)

对于您想要遍历图标和目的地的意思,我有点困惑,但是我是根据我的理解来回答。

如果数据顺序排列且数据长度相同,则可以使用多个列表视图显示数据。

您可以使用简单的listview实现它。我希望以下代码可以为您提供帮助。 如果您有任何疑问,请随时询问。

   List<String> items = [
    'Alimentação', 'Artigos para o lar', 'Beleza', 'Carros',
    'Computadores', 'Consertos', 'Construção', 'Ensino',
    'Esporte', 'Pet', 'Presentes', 'Religião',
    'Saúde', 'Serviços Gráficos', 'Serviços para o lar', 'Serviços profissionais',
  ];

  List<IconData> icones = [
    Icons.play_arrow, Icons.list, Icons.create_new_folder, Icons.add_alarm,
    Icons.insert_comment, Icons.drag_handle, Icons.ac_unit, Icons.adjust,
    Icons.airline_seat_recline_extra, Icons.forum, Icons.gamepad, Icons.hd,
    Icons.format_align_justify, Icons.keyboard, Icons.list, Icons.mail,
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(
          'Teste de app',
        ),
      ),
      drawer: Drawer(
        child: ListView.builder(
          itemCount: items.length,
          itemBuilder: (context, i){
            return ListTile(
              title: Text(items[i]),
              leading: Icon(icones[i]),
              trailing: Icon(Icons.chevron_right),
              onTap: (){
                Navigator.pop(context);
              },
            );
          },
        ),
      ),
      body: Container(
        child: Text(
            'Texto'
        ),
      ),
    );
  } 

结果:

enter image description here

答案 1 :(得分:0)

您可以使用其他方法移动ListTile构建逻辑。

//Builds a Drawer item using ListTile()
class BuildDrawerTile extends StatelessWidget {

  List<String> list;
  BuildDrawerTile({@required this.list});

  @override

  Widget build(BuildContext context) {

    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: _buildList(),
    );
  }

  List<Widget> _buildList() {
    List<Widget> widgets = [];
    for(String item in list ) {
      widgets.add(ListTile( //HERE EVERYTHING WORKS WELL AS I'M NOT USING CURLY BRACKETS
        title: Text(
          item,
          style: GoogleFonts.quicksand(
            textStyle: TextStyle(
              color: Color(0xFF808080),
              fontWeight: FontWeight.w300,
            ),
          ),
        ),
        leading: Icon(Icons.play_arrow), //HERE I NEEDED TO ITERATE SPECIFIC ICONS FOR EACH ITEM
        trailing: Icon(Icons.play_arrow),
        onTap: (){
          Navigator.pop(context); //IN THE FUTURE HERE I'LL ITERATE A THIRD LIST WITH THE DESTINATIONS
        },
      ),);
    }

    return widgets;
  }
}