Flutter:我可以向ListView添加标题行吗?

dav*_*idk 24 listview header flutter

对Flutter来说很新.我已经能够利用HTTP请求数据,构建ListView,编辑该列表中的行和其他基础知识.环境优美.

我已经设法将一个构造糟糕的Header拼凑成一个ListView ......但我知道这是不对的.我无法正确排列Header文本.

我看到Drawer类有一个DrawerHeader类,但是看不到ListView有一个ListViewHeader.

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text('Contacts'),
          actions: [
            new IconButton(icon: new Icon(Icons.add_circle),
                onPressed: getCustData
            ),
          ],
        ),
        //body:
        body: new Column(
            children: [
              new Row(
                  children: [
                    new Expanded(child: new Text('', style: new TextStyle(height: 3.0, fontSize: 15.2, fontWeight: FontWeight.bold,))),
                    new Expanded(child: new Text('First Name', style: new TextStyle(height: 3.0, fontSize: 15.2, fontWeight: FontWeight.bold,))),
                    new Expanded(child: new Text('Last Name', style: new TextStyle(height: 3.0, fontSize: 15.2, fontWeight: FontWeight.bold,))),
                    new Expanded(child: new Text('City', style: new TextStyle(height: 3.0, fontSize: 15.2, fontWeight: FontWeight.bold,))),
                    new Expanded(child: new Text('Customer Id', style: new TextStyle(height: 3.0, fontSize: 15.2, fontWeight: FontWeight.bold,))),
                    new Expanded(child: new Text('', style: new TextStyle(height: 3.0, fontSize: 15.2, fontWeight: FontWeight.bold,))),
                  ]
              ),

new Expanded(child:Container( child: ListView.builder( itemCount: data == null ? 0 : data.length, itemBuilder: (BuildContext context, int index) { return new InkWell( onTap: () { Navigator.push( context, new MaterialPageRoute( builder: (context) => new APIDetailView(data[index])), ); }, child: new ListTile( //return new ListTile( onTap: null, leading: new CircleAvatar( backgroundColor: Colors.blue, child: new Text(data[index]["FirstName"][0]), ), title: new Row( children: <Widget>[ new Expanded(child: new Text(data[index]["FirstName"])), new Expanded(child: new Text(data[index]["LastName"])), new Expanded(child: new Text(data[index]["Bill_City"])), new Expanded(child: new Text(data[index]["Customer_Id"])), ] ) ), ); }, //itemBuilder ), ), ), ] ) );
Run Code Online (Sandbox Code Playgroud)

}}

谢谢.

在此输入图像描述

naj*_*ira 35

将itemBuilder作为第一行返回标题:

ListView.builder(
    itemCount: data == null ? 1 : data.length + 1,
    itemBuilder: (BuildContext context, int index) {
        if (index == 0) {
            // return the header
            return new Column(...);
        }
        index -= 1;

        // return row
        var row = data[index];
        return new InkWell(... with row ...);
    },
);
Run Code Online (Sandbox Code Playgroud)

  • 您可以从 MediaQuery 获取屏幕的宽度。如何用百分比计算宽度? (3认同)
  • 我不想 这是一个移动应用程序……永远不知道我要处理的屏幕宽度是多少。 (2认同)

小智 18

您可以添加ContainerListViewColumn

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: Text("Demo App1"),
        ),
        body: Column(
          children: <Widget>[
            Container(
              height: 40.0,
              child: Row(
                children: <Widget>[
                  Container(
                      padding: EdgeInsets.all(4.0),
                      width: 100.0,
                      child: Text(
                        "Name",
                        style: TextStyle(fontSize: 18),
                      )),
                  Container(
                      padding: EdgeInsets.all(4.0),
                      width: 100.0,
                      child: Text(
                        "Age",
                        style: TextStyle(fontSize: 18),
                      )),
                ],
              ),
            ),
            Expanded(
              child: ListView.builder(
                itemCount: 100,
                itemBuilder: (BuildContext context, int index) {
                  return Row(
                    children: <Widget>[
                      Container(
                          padding: EdgeInsets.all(4.0),
                          width: 100.0,
                          child: Text(
                            "Name $index",
                            style: TextStyle(fontSize: 18),
                          )),
                      Container(
                        padding: EdgeInsets.all(4.0),
                        width: 100.0,
                        child: Text(
                          "Age $index",
                          style: TextStyle(fontSize: 18),
                        ),
                      )
                    ],
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)


小智 14

您可以像这样向项目列表中的第一项添加一列

  new ListView.builder(
    itemCount: litems.length,
    itemBuilder: (BuildContext ctxt, int index) {
      if (index == 0) {
        return Column(
          children: <Widget>[
            Header(),
            rowContent(index),
          ],
        );
      } else {
        return rowContent(index);
      }
    },
  )
Run Code Online (Sandbox Code Playgroud)


Kab*_*uda 10

使用数据表小部件!
该小部件允许您构建表格。 代码 : DataTable(columns: [], rows: [],)

例子 :

  DataTable(
   columns: [
     DataColumn(label: Text('Lang.')),
     DataColumn(label: Text('Year')),
   ],
   rows: [
     DataRow(cells: [DataCell(Text('Dart')), DataCell(Text('2010'))]),
     DataRow(cells: [DataCell(Text('Go')), DataCell(Text('2009'))]),
     DataRow(cells: [DataCell(Text('PHP')), DataCell(Text('1994'))]),
     DataRow(cells: [DataCell(Text('Java')), DataCell(Text('1995'))]),
   ],
)
Run Code Online (Sandbox Code Playgroud)

输出:

在此输入图像描述

您可以通过观看官方视频或访问flutter.dev了解有关DataTable的更多信息


dav*_*idk 8

这是我解决这个问题的方法。感谢najeira让我思考其他解决方案。

在第一个正文Column中,我为Header使用了与ListTile相同的布局。

因为在这种情况下,我的数据ListTile包括一个CircleAvatar,所以所有的水平间距都略微有些偏...渲染CircleAvatar的5列...然后是4个均匀间隔的列。

所以...我在第一个正文列中添加了一个ListTile,添加了一个backgroundColor为透明的CircleAvatar,然后添加了我的4个标题行。

        new ListTile(
        onTap: null,
        leading: new CircleAvatar(
          backgroundColor: Colors.transparent,
        ),
        title: Row(
            children: <Widget>[
              new Expanded(child: new Text("First Name")),
              new Expanded(child: new Text("Last Name")),
              new Expanded(child: new Text("City")),
              new Expanded(child: new Text("Id")),
            ]
        ),
      ),
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明


小智 7

看来您真正需要的是 DataTable 小部件而不是 ListView。它有一个可定制的标题,包括排序选项。

阅读文档,包括 api.flutter.dev 上的一些精彩示例:数据表类 在此输入图像描述


use*_*004 6

najeira 的解决方案简单易行,但你可以在不触及 index.html 的情况下获得相同且更灵活的结果。

您可以使用CustomScrollView 和 SliverList,而不是使用 listView,它在功能上与 listView 相同。

   return Scaffold(
      body: CustomScrollView(
        slivers: <Widget>[
          SliverToBoxAdapter(
            // you could add any widget
            child: ListTile(
              leading: CircleAvatar(
                backgroundColor: Colors.transparent,
              ),
              title: Row(
                children: <Widget>[
                  Expanded(child: Text("First Name")),
                  Expanded(child: Text("Last Name")),
                  Expanded(child: Text("City")),
                  Expanded(child: Text("Id")),
                ],
              ),
            ),
          ),
          SliverList(
            delegate: SliverChildBuilderDelegate(
              (context, index) {
                return InkWell(
                  onTap: () {
                    Navigator.push(
                      context,
                      MaterialPageRoute(
                          builder: (context) => APIDetailView(data[index])),
                    );
                  },
                  child: ListTile(
                    //return  ListTile(
                    leading: CircleAvatar(
                      backgroundColor: Colors.blue,
                      child: Text(data[index]["FirstName"][0]),
                    ),
                    title: Row(
                      children: <Widget>[
                        Expanded(child: Text(data[index]["FirstName"])),
                        Expanded(child: Text(data[index]["LastName"])),
                        Expanded(child: Text(data[index]["Bill_City"])),
                        Expanded(child: Text(data[index]["Customer_Id"])),
                      ],
                    ),
                  ),
                );
              },
              childCount: data == null ? 0 : data.length,
            ),
          ),
        ],
      ),
    );
Run Code Online (Sandbox Code Playgroud)


Mis*_*rov 5

我创建了listview_utils包来减少构建页眉和页脚列表项所需的样板代码。这是使用该包的示例代码:

import 'package:listview_utils/listview_utils.dart';

CustomListView(
  header: Container(
    child: Text('Header'),
  ),
  itemCount: items.length,
  itemBuilder: (BuildContext context, int index, _) {
    return ListTile(
      title: Text(item['title']),
    );
  },
);
Run Code Online (Sandbox Code Playgroud)

我正在维护这个包。