作者:李俊才 (jcLee95):https://blog.csdn.net/qq_28550263
 邮箱 :291148484@163.com
 本文地址:https://blog.csdn.net/qq_28550263/article/details/133411883
1. 功能描述
ListTile 组件表示一个包含一到三行文本的列表项,它可以选择带有图标或其它组件。
需要特别说明的是,虽然
ListTile经常与ListView一起使用,但它并不仅限于ListView。实际上,可以在许多其他布局中使用ListTile,以创建各种不同的用户界面元素。例如,可以将ListTile放置在Column、Row、Card等其他布局中,以创建自定义的列表项或卡片。
2. 主要属性
ListTile 组件有以下常用属性:
| 属性 | 描述 | 
|---|---|
leading | 列表项的前导部分,通常是一个图标或自定义小部件。 | 
title | 列表项的主要标题文本。 | 
subtitle | 列表项的副标题文本。 | 
trailing | 列表项的尾部部分,通常包含右侧图标或控件。 | 
isThreeLine | 布尔值,指示是否为三行列表项。如果为 true,则可以显示额外的文本行。否则,只有一行文本。 | 
dense | 布尔值,指示是否启用紧凑模式,紧凑模式下,文本和图标的大小将减小。 | 
visualDensity | 控制布局紧凑性的视觉密度。 | 
shape | 定义列表项的形状的形状对象。 | 
style | 文本的样式。 | 
selectedColor | 选定时的背景颜色。 | 
iconColor | 图标的颜色。 | 
textColor | 文本的颜色。 | 
titleTextStyle | 标题文本的样式。 | 
subtitleTextStyle | 副标题文本的样式。 | 
leadingAndTrailingTextStyle | 前导和尾部部分文本的样式。 | 
contentPadding | 内容的内边距。 | 
enabled | 布尔值,指示列表项是否可用。如果为 false,则列表项将不可点击。 | 
onTap | 点击列表项时触发的回调函数。 | 
onLongPress | 长按列表项时触发的回调函数。 | 
onFocusChange | 获得或失去焦点时触发的回调函数。 | 
mouseCursor | 指针悬停在列表项上时的鼠标指针样式。 | 
selected | 布尔值,指示列表项是否已选择。 | 
focusColor | 获取焦点时的背景颜色。 | 
hoverColor | 鼠标悬停时的背景颜色。 | 
splashColor | 点击列表项时的水波纹颜色。 | 
focusNode | 用于处理焦点状态的 FocusNode 对象。 | 
autofocus | 布尔值,指示列表项是否自动获取焦点。 | 
tileColor | 列表项的背景颜色。 | 
selectedTileColor | 选中列表项时的背景颜色。 | 
enableFeedback | 是否启用触觉反馈。 | 
horizontalTitleGap | 标题与前导/尾部之间的水平间距。 | 
minVerticalPadding | 最小垂直内边距。 | 
minLeadingWidth | 最小前导宽度。 | 
titleAlignment | 标题文本的对齐方式。 | 
3. ListTile的组成元素
-  
前导部分(leading):通常是显示在
ListTile左侧的部分,可以是一个图标(Icon)、缩略图(Image)或其他前导元素。 -  
主标题(title):通常是
ListTile的主要文本内容,显示在前导部分(如果有的话)的右侧,用于描述列表项的主要信息。 -  
副标题(subtitle):可选项,显示在主标题下面,用于显示列表项的附加信息或次要信息。
 -  
尾部部分(trailing):通常是显示在
ListTile右侧的部分,可以是一个图标(Icon)、按钮或其他尾部元素。 
这些是 ListTile 的基本组成部分,可以根据需要自定义和组合这些元素,以创建符合你设计需求的列表项。
4. 案例:一个简单的购物车UI
import 'package:flutter/material.dart';
void main() {
  runApp(const MyApp());
}
class MyApp extends StatelessWidget {
  const MyApp({super.key});
  
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: ShoppingCartScreen(),
    );
  }
}
class ShoppingCartScreen extends StatelessWidget {
  const ShoppingCartScreen({super.key});
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('购物车'),
      ),
      body: ListView.builder(
        itemCount: 9,
        itemBuilder: (context, index) {
          return ShoppingCartItem(
            productName: '商品$index',
            productDescription: '商品$index的一些描述',
            productQuantity: 1, // 产品数量
            productImageUrl:
                'https://gw.alicdn.com/bao/uploaded/i4/1711217080/O1CN018eotkR22Ah1q4eDcs_!!1711217080.jpg_300x300q90.jpg', // 替换为你的网络图片 URL
          );
        },
      ),
    );
  }
}
class ShoppingCartItem extends StatefulWidget {
  final String productName;
  final String productDescription;
  final int productQuantity;
  final String productImageUrl;
  const ShoppingCartItem({
    Key? key,
    required this.productName,
    required this.productDescription,
    required this.productQuantity,
    required this.productImageUrl,
  }) : super(key: key);
  
  State<ShoppingCartItem> createState() => _ShoppingCartItemState();
}
class _ShoppingCartItemState extends State<ShoppingCartItem> {
  bool isChecked = false;
  
  Widget build(BuildContext context) {
    return Card(
      child: ListTile(
        leading: Checkbox(
          value: isChecked,
          onChanged: (value) {
            setState(() {
              isChecked = value!;
            });
          },
        ),
        title: Text(widget.productName),
        subtitle: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(widget.productDescription),
            Text('数量:${widget.productQuantity}'),
          ],
        ),
        trailing: Image.network(
          widget.productImageUrl,
          width: 50,
          height: 50,
          fit: BoxFit.cover,
        ),
      ),
    );
  }
}
 
效果如下:

5. 案例2:一个新闻列表
import 'package:flutter/material.dart';
void main() {
  runApp(const MyApp());
}
class MyApp extends StatelessWidget {
  const MyApp({super.key});
  
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: NewsListScreen(),
    );
  }
}
class NewsListScreen extends StatefulWidget {
  const NewsListScreen({super.key});
  
  State<NewsListScreen> createState() => _NewsListScreenState();
}
class _NewsListScreenState extends State<NewsListScreen> {
  List<String> newsList = List.generate(5, (index) => '新闻标题 $index');
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('新闻列表'), // 设置页面标题
      ),
      body: ListView.builder(
        itemCount: newsList.length, // 使用列表的长度
        itemBuilder: (context, index) {
          return NewsListItem(
            headline: newsList[index], // 新闻标题
            description: '新闻描述 $index', // 新闻描述
            imageUrl:
                'https://pics6.baidu.com/feed/5ab5c9ea15ce36d3733d7035255cf48be950b132.jpeg@f_auto?token=29586d3d429228d0a2c251be0f9a8a67', // 替换为你的新闻图片网络 URL
            onDelete: () {
              // 处理删除事件
              setState(() {
                newsList.removeAt(index); // 移除对应索引的新闻标题
              });
            },
          );
        },
      ),
    );
  }
}
class NewsListItem extends StatelessWidget {
  final String headline;
  final String description;
  final String imageUrl;
  final VoidCallback onDelete;
  const NewsListItem({
    Key? key,
    required this.headline,
    required this.description,
    required this.imageUrl,
    required this.onDelete,
  }) : super(key: key);
  
  Widget build(BuildContext context) {
    return Card(
      child: ListTile(
        contentPadding: const EdgeInsets.all(16.0),
        leading: Image.network(
          imageUrl, // 使用网络图片 URL
          width: 80,
          height: 80,
          fit: BoxFit.cover,
        ),
        title: Text(
          headline,
          style: const TextStyle(fontWeight: FontWeight.bold),
        ),
        subtitle: Text(description),
        trailing: IconButton(
          icon: const Icon(Icons.delete),
          onPressed: onDelete, // 触发删除操作
        ),
        onTap: () {
          // 处理点击事件,例如打开新闻详情页面
          // 这里可以添加你的代码逻辑
        },
      ),
    );
  }
}
 
效果如下:

6. 案例3:模拟文件资源管理器页面
import 'package:flutter/material.dart';
void main() {
  runApp(const FileExplorerApp());
}
class FileExplorerApp extends StatelessWidget {
  const FileExplorerApp({super.key});
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('文件资源管理器'),
        ),
        body: const FileExplorerUI(),
      ),
    );
  }
}
class FileExplorerUI extends StatefulWidget {
  const FileExplorerUI({super.key});
  
  State<FileExplorerUI> createState() => _FileExplorerUIState();
}
class _FileExplorerUIState extends State<FileExplorerUI> {
  SortMode _sortMode = SortMode.name;
  
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: [
        Row(
          mainAxisAlignment: MainAxisAlignment.end,
          children: [
            IconButton(
              icon: const Icon(Icons.view_list),
              onPressed: () {
                setState(() {});
              },
            ),
            IconButton(
              icon: const Icon(Icons.view_module),
              onPressed: () {
                setState(() {});
              },
            ),
            IconButton(
              icon: const Icon(Icons.view_headline),
              onPressed: () {
                setState(() {});
              },
            ),
            DropdownButton<SortMode>(
              value: _sortMode,
              onChanged: (value) {
                setState(() {
                  _sortMode = value!;
                });
              },
              items: SortMode.values
                  .map<DropdownMenuItem<SortMode>>(
                    (mode) => DropdownMenuItem(
                      value: mode,
                      child: Text(mode.toString().split('.').last),
                    ),
                  )
                  .toList(),
            ),
          ],
        ),
        Expanded(
          child: ListView.builder(
            itemCount: 10, // 虚拟数据,实际根据文件列表长度设置
            itemBuilder: (context, index) {
              return ListTile(
                leading: const Icon(Icons.folder), // 根据文件类型设置图标
                title: Text('文件或文件夹 $index'), // 根据文件名称设置
                subtitle: const Text('文件大小: 1 KB'), // 根据文件大小设置
                trailing: const Text('修改日期: 2023-01-01'), // 根据修改日期设置
              );
            },
          ),
        ),
      ],
    );
  }
}
enum ViewMode { details, largeIcon, smallIcon }
enum SortMode { name, size, type, date }
 
效果如图所示:



















![web:[极客大挑战 2019]BabySQL](https://img-blog.csdnimg.cn/d1fbf28b01da4d7aa60be045892e8e0b.png)
