Flutter笔记 - ListTile组件及其应用

简介: Flutter笔记 - ListTile组件及其应用

Flutter笔记ListTile组件及其应用


作者李俊才 (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 放置在 ColumnRowCard 等其他布局中,以创建自定义的列表项或卡片。

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的组成元素

  1. 前导部分(leading):通常是显示在 ListTile 左侧的部分,可以是一个图标(Icon)、缩略图(Image)或其他前导元素。
  2. 主标题(title):通常是 ListTile 的主要文本内容,显示在前导部分(如果有的话)的右侧,用于描述列表项的主要信息。
  3. 副标题(subtitle):可选项,显示在主标题下面,用于显示列表项的附加信息或次要信息。
  4. 尾部部分(trailing):通常是显示在 ListTile 右侧的部分,可以是一个图标(Icon)、按钮或其他尾部元素。

这些是 ListTile 的基本组成部分,可以根据需要自定义和组合这些元素,以创建符合你设计需求的列表项。

4. 案例:一个简单的购物车UI

import 'package:flutter/material.dart';
void main() {
  runApp(const MyApp());
}
class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: ShoppingCartScreen(),
    );
  }
}
class ShoppingCartScreen extends StatelessWidget {
  const ShoppingCartScreen({super.key});
  @override
  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);
  @override
  State<ShoppingCartItem> createState() => _ShoppingCartItemState();
}
class _ShoppingCartItemState extends State<ShoppingCartItem> {
  bool isChecked = false;
  @override
  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});
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: NewsListScreen(),
    );
  }
}
class NewsListScreen extends StatefulWidget {
  const NewsListScreen({super.key});
  @override
  State<NewsListScreen> createState() => _NewsListScreenState();
}
class _NewsListScreenState extends State<NewsListScreen> {
  List<String> newsList = List.generate(5, (index) => '新闻标题 $index');
  @override
  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);
  @override
  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});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('文件资源管理器'),
        ),
        body: const FileExplorerUI(),
      ),
    );
  }
}
class FileExplorerUI extends StatefulWidget {
  const FileExplorerUI({super.key});
  @override
  State<FileExplorerUI> createState() => _FileExplorerUIState();
}
class _FileExplorerUIState extends State<FileExplorerUI> {
  SortMode _sortMode = SortMode.name;
  @override
  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 }

效果如图所示:

目录
相关文章
|
2月前
|
开发框架 前端开发 Android开发
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
271 4
|
2月前
|
缓存 监控 前端开发
优化 Flutter 应用启动速度的策略,涵盖理解启动过程、资源加载优化、减少初始化工作、界面布局优化、异步初始化、预加载关键数据、性能监控与分析等方面
本文探讨了优化 Flutter 应用启动速度的策略,涵盖理解启动过程、资源加载优化、减少初始化工作、界面布局优化、异步初始化、预加载关键数据、性能监控与分析等方面,并通过案例分析展示了具体措施和效果,强调了持续优化的重要性及未来优化方向。
90 10
|
1天前
|
Dart 前端开发
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
2月前
|
存储 调度 数据安全/隐私保护
鸿蒙Flutter实战:13-鸿蒙应用打包上架流程
鸿蒙应用打包上架流程包括创建应用、打包签名和上传应用。首先,在AppGallery Connect中创建项目、APP ID和元服务。接着,使用Deveco进行手动签名,生成.p12和.csr文件,并在AppGallery Connect中上传CSR文件获取证书。最后,配置签名并打包生成.app文件,上传至应用市场。常见问题包括检查签名配置文件是否正确。参考资料:[应用/服务签名](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/ide-signing-V5)。
92 3
鸿蒙Flutter实战:13-鸿蒙应用打包上架流程
|
2月前
|
传感器 前端开发 Android开发
在 Flutter 开发中,插件开发与集成至关重要,它能扩展应用功能,满足复杂业务需求
在 Flutter 开发中,插件开发与集成至关重要,它能扩展应用功能,满足复杂业务需求。本文深入探讨了插件开发的基本概念、流程、集成方法、常见类型及开发实例,如相机插件的开发步骤,同时强调了版本兼容性、性能优化等注意事项,并展望了插件开发的未来趋势。
56 2
|
2月前
|
存储 Dart
Flutter&鸿蒙next 实现一个计算器应用
本文介绍了如何使用 Flutter 创建一个简单的计算器应用,包括基本的加减乘除运算。文章详细讲解了界面布局、计算逻辑和状态管理的实现步骤,通过具体的代码示例展示了如何构建计算器界面、处理用户输入和显示计算结果。
114 0
|
2月前
|
传感器 开发框架 物联网
鸿蒙next选择 Flutter 开发跨平台应用的原因
鸿蒙(HarmonyOS)是华为推出的一款旨在实现多设备无缝连接的操作系统。为了实现这一目标,鸿蒙选择了 Flutter 作为主要的跨平台应用开发框架。Flutter 的跨平台能力、高性能、丰富的生态支持和与鸿蒙系统的良好兼容性,使其成为理想的选择。通过 Flutter,开发者可以高效地构建和部署多平台应用,推动鸿蒙生态的快速发展。
345 0
|
7天前
|
前端开发 Java 开发工具
【03】完整flutter的APP打包流程-以apk设置图标-包名-签名-APP名-打包流程为例—-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈 章节内容【03】
【03】完整flutter的APP打包流程-以apk设置图标-包名-签名-APP名-打包流程为例—-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈 章节内容【03】
【03】完整flutter的APP打包流程-以apk设置图标-包名-签名-APP名-打包流程为例—-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈 章节内容【03】
|
3天前
|
缓存 前端开发 Android开发
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
|
3月前
|
Android开发 iOS开发 容器
鸿蒙harmonyos next flutter混合开发之开发FFI plugin
鸿蒙harmonyos next flutter混合开发之开发FFI plugin

热门文章

最新文章