flutter divider:我如何在代码中的每一行之间添加分隔符?

时间:2018-06-04 19:36:24

标签: android flutter

我怎样才能将divider添加到列表中?我使用flatter for android。我想在每一行之间添加一个分隔符,我想要对分隔符进行着色并添加样式。

我尝试添加new divider();,但我收到了错误。我也试过return new divider();

以下是我的应用的屏幕截图:

这是我的代码:

import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';

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

class MyApp extends StatelessWidget {
  const MyApp();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
          primarySwatch: Colors.purple,

          buttonTheme: const ButtonThemeData(
            textTheme: ButtonTextTheme.primary,
          )
      ),
      home: const MyHomePage(),
    );
  }
}

class Kitten {
  const Kitten({this.name, this.description, this.age, this.imageurl});

  final String name;
  final String description;
  final int age;
  final String imageurl;
}

final List<Kitten> _kittens = <Kitten>[
  Kitten(
      name: "kitchen",
      description: "mehraboon",
      age: 2,
      imageurl:
      "https://images.pexels.com/photos/104827/cat-pet-animal-domestic- 
      104827.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=350",
  ),
  Kitten(
      name: "garage",
      description: "khashen",
      age: 1,
      imageurl:
      "https://images.pexels.com/photos/4602/jumping-cute-playing-animals.jpg? 
      auto=compress&cs=tinysrgb&dpr=2&h=350",
  ),
  Kitten(
      name: "bedroom",
      description: "khar zoor",
      age: 5,
      imageurl:
      "https://images.pexels.com/photos/978555/pexels-photo-978555.jpeg? 
      auto=compress&cs=tinysrgb&dpr=2&h=350",
  ),
  Kitten(
      name: "living room",
      description: "chorto",
      age: 3,
      imageurl:
      "https://images.pexels.com/photos/209037/pexels-photo-209037.jpeg? 
      auto=compress&cs=tinysrgb&dpr=2&h=350",
  ),
];

class MyHomePage extends StatelessWidget {
  const MyHomePage({Key key}) : super(key: key);

  Widget _dialogBuilder(BuildContext context, Kitten kitten) {
    return SimpleDialog(contentPadding: EdgeInsets.zero, children: [
      Image.network(kitten.imageurl, fit: BoxFit.fill),
      Padding(
          padding: const EdgeInsets.all(16.0),
          child:
          Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
            Text(kitten.name),
            Text('${kitten.age}'),
            SizedBox(
              height: 16.0,
            ),
            Text(kitten.description),
            Align(
              alignment: Alignment.centerRight,
              child: Wrap(
                children: [
                  FlatButton(onPressed: () {}, child: const
                  Text("noooo!"),color: Colors.red,),
                  Padding(padding: const EdgeInsets.all(2.0),),
                  RaisedButton(onPressed: () {}, child: const
                  Text("yesss!"),color: Colors.green)
                ],
              ),
            )
          ]))
    ]);
  }

  Widget _listItemBuilder(BuildContext context, int index) {
    return new GestureDetector(

      onTap: () => showDialog(
          context: context,
          builder: (context) => _dialogBuilder(context, _kittens[index])),
      child:
      Container(

        padding: EdgeInsets.all( 16.0),
        alignment: Alignment.centerLeft,
        child: Text(_kittens[index].name,
            style: Theme.of(context).textTheme.headline),

      ),


    ) ;

  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Keys"),
        centerTitle: true,


      ),
      body: ListView.builder(
        itemCount: _kittens.length,
        itemExtent: 60.0,
        itemBuilder: _listItemBuilder,

      ),
    );
  }
}

10 个答案:

答案 0 :(得分:17)

最正确的方法是使用 ListView.separated

ListView.separated(
     itemCount: 25,
     separatorBuilder: (BuildContext context, int index) => Divider(),
     itemBuilder: (BuildContext context, int index) {
       return ListTile(
         title: Text('item $index'),
       );
     },
);

答案 1 :(得分:16)

有很多方法可以做同样的事情。我在这里比较一下。

获取简短的静态列表

使用ListTile.divideTiles

enter image description here

ListView(
  children: ListTile.divideTiles( //          <-- ListTile.divideTiles
      context: context,
      tiles: [
        ListTile(
          title: Text('Horse'),
        ),
        ListTile(
          title: Text('Cow'),
        ),
        ListTile(
          title: Text('Camel'),
        ),
        ListTile(
          title: Text('Sheep'),
        ),
        ListTile(
          title: Text('Goat'),
        ),
      ]
  ).toList(),
)

获取较长的动态列表

使用ListView.separated

enter image description here

ListView.separated(
  itemCount: 100,
  itemBuilder: (context, index) {
    return ListTile(
      title: Text('$index sheep'),
    );
  },
  separatorBuilder: (context, index) {
    return Divider();
  },
)

这将为每个项目返回两个小部件,最后一个项目除外。 separatorBuilder用于添加分隔符。

用于在最后一项之后添加分隔线

创建一个使用Divider或BoxDecoration的自定义项目小部件。

使用分隔线

enter image description here

final items = ['Horse', 'Cow', 'Camel', 'Sheep', 'Goat'];

@override
Widget build(BuildContext context) {
  return ListView.builder(
    itemCount: items.length,
    itemBuilder: (context, index) {
      return Column(
        children: <Widget>[
          ListTile(
            title: Text(items[index]),
          ),
          Divider(), //                           <-- Divider
        ],
      );
    },
  );
}

使用BoxDecoration

enter image description here

final items = ['Horse', 'Cow', 'Camel', 'Sheep', 'Goat'];

@override
Widget build(BuildContext context) {
  return ListView.builder(
    itemCount: items.length,
    itemBuilder: (context, index) {
      return Container(
        decoration: BoxDecoration( //                    <-- BoxDecoration
          border: Border(bottom: BorderSide()),
        ),
        child: ListTile(
          title: Text(items[index]),
        ),
      );
    },
  );
}

Divider和BoxDecoration都可以自定义,只要行高和颜色都可以。 Divider也有一个缩进选项,但是您可以使用BoxDecoration进行一些填充来做同样的事情。

更多样式

使用卡

enter image description here

final items = ['Horse', 'Cow', 'Camel', 'Sheep', 'Goat'];

@override
Widget build(BuildContext context) {
  return ListView.builder(
    itemCount: items.length,
    itemBuilder: (context, index) {
      return Card( //                           <-- Card
        child: ListTile(
          title: Text(items[index]),
        ),
      );
    },
  );
}

答案 2 :(得分:7)

将您的小部件放在容器中,BoxDecoration为

Container(
   child: YourWidgetHere(),
   decoration: BoxDecoration(
      border: Border(bottom: BorderSide(color: Colors.black26))),
);

答案 3 :(得分:5)

在涵盖的flutter getting started tutorial上,他们提供的解决方案是这样的(可能需要一些调整):

  body: ListView.builder(
    itemCount: _kittens.length,
    itemExtent: 60.0,
    itemBuilder: (context, i) {
        // Add a one-pixel-high divider widget before each row in theListView.
        if (i.isOdd) return new Divider(color: Colors.purple); // notice color is added to style divider

        return _listItemBuilder();
      },
  ),
  ...

这应该添加分隔符,同时考虑奇数行和偶数行。

也为分隔符颜色&#34;着色。到Divider Class

new Divider(color: Colors.purple);

答案 4 :(得分:3)

查看此问题: ListView.builder should let clients specify a divider 明确表明:

  1. 如果您需要使用动态元素构建列表,那么现在您必须自己处理此问题。我建议在行窗口小部件构建中,在底部添加一个List Divider,其中有一列或其他内容,最后一个除外(您可以测试index == listData.length - 1)。

  2. 但是,如果像显示的示例一样,您已经事先知道所有列表数据,或者在没有ListView.builder的情况下进行构建,则可以并且应该使用命名构造函数{{1 }}

答案 5 :(得分:1)

this之后,只需添加Divider():

         Column(
                children: <Widget>[
                  Container(
                    padding: EdgeInsets.all(16.0),
                    child: Column(
                      children: <Widget>[
                        Image.network(video["imageUrl"]),
                        Container(
                          height: 6.0,
                        ),
                        Text(
                          video["name"],
                          textScaleFactor: 1.05,
                          style: TextStyle(fontWeight: FontWeight.bold),
                        ),
                      ],
                    ),
                  ),
                  Divider(
                    color: Theme.of(context).primaryColor,
                  )
                ],
              );                                                                           

答案 6 :(得分:0)

那是使用容器的另一种方式。

@service
@RequiredArgsConstructor
public class MailService {

    @Resource(name = "mailExchangeService")
    private final ExchangeService service;

    public EmailMessage sendMail(String subscription, String subject, String body, File csvFiles) {
        EmailMessage message = null;

        try{
            message = new EmailMessage(this.service);

            message.setItemClass("IPM.Note");
            message.setSubject(subject);
            message.setBody(new MessageBody(bodyType.HTML, body));
            message.getAttachments().addFileAttachment(csvFiles.getAbsolutePath());
            message.getToRecipients().add(subscription);
            message.send();
        }catch (Exception e) {
            log.error("Error while sending mail", e);
        }
        return  message;
    }
}

答案 7 :(得分:0)

飞镖 2.3

另一种方式,特别是对于通用的非列表视图:在集合 (link) 中使用 for... 展开运算符

Column(
   children: [
     for(var i=0; i<4; i+=1)
     ...[Container(height: 100, width: 100),
         Divider()
      ]])

答案 8 :(得分:0)

该问题假设我们可以访问 material.dart 以进行 Android 样式(ListTileDivider)。如果您想要 Cupertino 风格,我们可以:

  1. 对行使用 Column 视图包装器,并添加高度为 1 的 Container

     Column(
       children: <Widget>[
         row, // A custom Row
         Padding(
           padding: const EdgeInsets.only(
             left: 16,  // Adjust separator left padding.
             right: 16, // Adjust separator right padding.
           ),
           child: Container(
             height: 1,
             color: Styles.productRowDivider, // Custom style
           ),
         ),
       ],
     );
    
  2. Dividercupertino.dart 中不可用。我们可以对 Container 使用相同的 ListView.separated 技术:

     ListView.separated(
       itemCount: 100,
       itemBuilder: (context, index) {
         return row;
       },
       separatorBuilder: (context, index) {
         return Container(
                 height: 1,
                 color: Styles.productRowDivider, // Custom style
               );
       },
     );
    

答案 9 :(得分:-1)

像这样创建一个容器

Container(height: 1, color: Colors.grey),

并像这样添加您的 ListTile

 ListView.builder(
  itemCount: _feed.items.length,
  itemBuilder: (BuildContext context, int index) {
    final item = _feed.items[index];

     return  Column(
         children: <Widget>[
      Container(height: 1, color: Colors.grey),  //Container for devider
      ListTile(                                  //Your tile item
      title: title(item.title),
      subtitle: subtitle(item.pubDate),
      leading: thumbnail(item.enclosure.url),
      trailing: rightIcon(),
      contentPadding: EdgeInsets.all(5.0),
      onTap: () => openFeed(item.link),
    )]);
  },
);

现在您可以在我的屏幕截图中看到最终输出

enter image description here [1]:https://i.stack.imgur.com/EZuIg.jpg