首页 > 解决方案 > 在 ListtTile Tap 上显示一行

问题描述

我的 ListView.builder 有一个 Column 子级以及该列的 ListTile 和 Row 子级。我想要实现的是,当用户点击 ListTile 项目时,它将使其 Row 可见。如何获取单击了哪个 ListTile 项目并且连接到它的行将可见?

这是代码:

class DebitInvoiceLineList extends StatefulWidget {
  
  final List<DebitInvoiceLine> dInvoiceLines;

  DebitInvoiceLineList({
    @required
    
    this.dInvoiceLines
  });

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

class _DebitInvoiceLineListState extends State<DebitInvoiceLineList> {
  bool visibleEdit = false;

  _changed(bool visibility) {
    setState(() {
      visibleEdit = visibility;
    });
  }

  @override
  Widget build(BuildContext context) {


    return NotificationListener<OverscrollIndicatorNotification>(
      onNotification: (OverscrollIndicatorNotification overScroll) {
        overScroll.disallowGlow();
        return false;
      },
      
      child: ListView.builder(
          
          itemCount: widget.dInvoiceLines.length,
          shrinkWrap: true,
          
          itemBuilder: (context, int index) {
            return Column(
              children: <Widget>[
                ListTile(
                  key: Key(index.toString()),
                  leading: Padding(
                    padding: const EdgeInsets.only(top: 5.0),
                    child: Text(
                      (index + 1).toString() + " - "
                    ),
                  ),
                  title: Text(widget.dInvoiceLines[index].description),
                  trailing: Text(
                      NumberFormat.currency(locale: 'da').format(widget.dInvoiceLines[index].price),
                      style: dSecondHeaderStyle
                  ),
                  onTap: () {
                    setState(() {
                      visibleEdit = !visibleEdit;
                    });
                  }
                ),
                Visibility(
                  visible: visibleEdit,
                  key: Key(index.toString()),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      Text("Edit"),
                      Text("Delete")
                    ],
                  ),
                )
              ],
            );
            
          },
        ),
      
    );

我可以用钥匙来做吗?或者我怎样才能得到正确的物品?

标签: flutterflutter-layout

解决方案


利用ExpansionTile小部件,在颤振中我们使用 ExpansionTile 来实现这种行为。

检查示例代码:


import 'package:flutter/material.dart';

class ExpansionTileSample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('ExpansionTile'),
        ),
        body: ListView.builder(
          itemBuilder: (BuildContext context, int index) =>
              EntryItem(data[index]),
          itemCount: data.length,
        ),
      ),
    );
  }
}

// One entry in the multilevel list displayed by this app.
class Entry {
  Entry(this.title, [this.children = const <Entry>[]]);

  final String title;
  final List<Entry> children;
}

// The entire multilevel list displayed by this app.
final List<Entry> data = <Entry>[
  Entry(
    'Chapter A',
    <Entry>[
      Entry(
        'Section A0',
        <Entry>[
          Entry('Item A0.1'),
          Entry('Item A0.2'),
          Entry('Item A0.3'),
        ],
      ),
      Entry('Section A1'),
      Entry('Section A2'),
    ],
  ),
  Entry(
    'Chapter B',
    <Entry>[
      Entry('Section B0'),
      Entry('Section B1'),
    ],
  ),
  Entry(
    'Chapter C',
    <Entry>[
      Entry('Section C0'),
      Entry('Section C1'),
      Entry(
        'Section C2',
        <Entry>[
          Entry('Item C2.0'),
          Entry('Item C2.1'),
          Entry('Item C2.2'),
          Entry('Item C2.3'),
        ],
      ),
    ],
  ),
];

// Displays one Entry. If the entry has children then it's displayed
// with an ExpansionTile.
class EntryItem extends StatelessWidget {
  const EntryItem(this.entry);

  final Entry entry;

  Widget _buildTiles(Entry root) {
    if (root.children.isEmpty) return ListTile(title: Text(root.title));
    return ExpansionTile(
      key: PageStorageKey<Entry>(root),
      title: Text(root.title),
      children: root.children.map(_buildTiles).toList(),
    );
  }

  @override
  Widget build(BuildContext context) {
    return _buildTiles(entry);
  }
}

void main() {
  runApp(ExpansionTileSample());
}

您可以创建自己的数据模型。

参考: https ://flutter.dev/docs/catalog/samples/expansion-tile-sample


推荐阅读