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});

  
  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 }

效果如图所示:

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Flutter中的TextField是一个常用的输入控件,它允许用户在应用程序中输入文本。 TextField通常用于表单中,可以接收用户输入的文本,比如用户名、密码、电子邮件地址等。 以下是一个基本的TextField示例: ```dart TextField( decoration: InputDecoration( hintText: '请输入文本', ), ); ``` 在上面的示例中,我们使用了decoration属性来设置TextField的外观,其中hintText属性用于设置提示文本。 TextField还有许多其他的属性可以设置,比如maxLength(允许输入的最大长度)、keyboardType(键盘类型)、obscureText(是否隐藏输入内容)等等。 下面是一个更完整的TextField示例: ```dart class MyTextField extends StatefulWidget { @override _MyTextFieldState createState() => _MyTextFieldState(); } class _MyTextFieldState extends State<MyTextField> { final TextEditingController _controller = TextEditingController(); @override Widget build(BuildContext context) { return TextField( controller: _controller, maxLength: 10, keyboardType: TextInputType.text, obscureText: true, decoration: InputDecoration( hintText: '请输入文本', labelText: '文本框', prefixIcon: Icon(Icons.text_fields), suffixIcon: IconButton( icon: Icon(Icons.clear), onPressed: () { setState(() { _controller.clear(); }); }, ), border: OutlineInputBorder(), ), onChanged: (value) { print('输入的文本为:$value'); }, ); } } ``` 在上面的示例中,我们使用了TextEditingController来控制TextField的文本内容,maxLength属性限制了用户输入的最大长度为10,keyboardType属性指定了键盘类型为文本类型,obscureText属性设置为true表示隐藏输入内容。 此外,我们还设置了decoration属性来自定义TextField的外观,包括了输入提示文本、标签文本、前缀图标、后缀图标和边框样式等。 最后,我们通过onChanged回调函数来监听用户输入的文本,并打印出来。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jcLee95

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值