Flutter for OpenHarmony 猫咪管家App实战 - 品种图鉴实现
本文实现了一个猫咪品种图鉴功能,展示10种常见猫咪的基本信息。每个品种以可展开卡片形式呈现,包含原产地、体重、寿命、性格和护理要点等关键信息。采用不同颜色区分品种,使用ExpansionTile实现展开/折叠交互。数据采用静态List存储,界面简洁清晰,适合作为宠物知识科普工具。功能不涉及数据修改,纯展示型设计,便于用户快速了解各品种特点。

想了解不同猫咪品种的特点?今天我们来实现一个品种图鉴功能,展示常见猫咪品种的基本信息,包括原产地、体重、寿命、性格和护理要点。
功能设计
品种图鉴需要实现:
- 展示多种猫咪品种
- 每个品种可以展开查看详情
- 显示体重、寿命、性格、护理等信息
- 不同品种用不同颜色区分
这是一个纯展示型的页面,不涉及数据的增删改。
依赖导入
引入需要的包:
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
这个页面不需要Provider,数据是静态的。
screenutil用于屏幕适配。
无状态组件
品种图鉴是纯展示页面:
class BreedGuideScreen extends StatelessWidget {
const BreedGuideScreen({super.key});
没有需要维护的状态,用StatelessWidget。
数据直接定义在组件内部。
品种数据定义
用List存储品种信息:
final List<Map<String, dynamic>> _breeds = const [
{
'name': '中华田园猫',
'origin': '中国',
'weight': '3-6 kg',
'lifespan': '12-20年',
'personality': '聪明、独立、适应力强',
'care': '易于照顾,抵抗力强',
'color': Colors.orange,
},
{
'name': '英国短毛猫',
'origin': '英国',
'weight': '4-8 kg',
'lifespan': '12-17年',
'personality': '温顺、安静、友善',
'care': '需要定期梳毛,注意体重',
'color': Colors.blue,
},
每个品种用Map存储各项信息。
color用于区分不同品种的视觉效果。
更多品种数据:
{
'name': '美国短毛猫',
'origin': '美国',
'weight': '3-6 kg',
'lifespan': '15-20年',
'personality': '活泼、聪明、好奇',
'care': '适应力强,易于照顾',
'color': Colors.green,
},
{
'name': '布偶猫',
'origin': '美国',
'weight': '4-9 kg',
'lifespan': '12-17年',
'personality': '温顺、粘人、安静',
'care': '需要经常梳毛,注意心脏健康',
'color': Colors.purple,
},
布偶猫体型较大,体重可达9公斤。
每个品种的护理要点都不同。
继续添加品种:
{
'name': '波斯猫',
'origin': '伊朗',
'weight': '3-7 kg',
'lifespan': '10-17年',
'personality': '安静、温和、优雅',
'care': '需要每日梳毛,注意眼睛清洁',
'color': Colors.pink,
},
{
'name': '暹罗猫',
'origin': '泰国',
'weight': '2.5-5 kg',
'lifespan': '12-20年',
'personality': '活泼、聪明、爱叫',
'care': '需要陪伴,注意牙齿健康',
'color': Colors.brown,
},
波斯猫需要每日梳毛,护理要求较高。
暹罗猫比较爱叫,这是品种特点。
更多品种:
{
'name': '缅因猫',
'origin': '美国',
'weight': '5-11 kg',
'lifespan': '10-15年',
'personality': '友善、温和、聪明',
'care': '需要大空间,定期梳毛',
'color': Colors.teal,
},
{
'name': '苏格兰折耳猫',
'origin': '苏格兰',
'weight': '2.5-6 kg',
'lifespan': '11-15年',
'personality': '温顺、安静、亲人',
'care': '注意关节健康,避免繁殖',
'color': Colors.indigo,
},
缅因猫是大型猫,体重可达11公斤。
折耳猫有遗传性关节问题,需要特别注意。
最后两个品种:
{
'name': '俄罗斯蓝猫',
'origin': '俄罗斯',
'weight': '3-5.5 kg',
'lifespan': '15-20年',
'personality': '安静、害羞、忠诚',
'care': '低过敏,易于照顾',
'color': Colors.blueGrey,
},
{
'name': '孟加拉猫',
'origin': '美国',
'weight': '4-7 kg',
'lifespan': '12-16年',
'personality': '活泼、好奇、爱玩水',
'care': '需要大量运动和互动',
'color': Colors.amber,
},
];
俄罗斯蓝猫是低过敏品种,适合过敏体质的人。
孟加拉猫精力旺盛,需要大量运动。
页面结构
build方法构建列表:
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('品种图鉴')),
body: ListView.builder(
padding: EdgeInsets.all(16.w),
itemCount: _breeds.length,
itemBuilder: (context, index) => _buildBreedCard(_breeds[index]),
),
);
}
ListView.builder按需构建列表项,性能更好。
itemCount是列表长度,itemBuilder构建每一项。
品种卡片组件
用ExpansionTile实现可展开的卡片:
Widget _buildBreedCard(Map<String, dynamic> breed) {
return Card(
margin: EdgeInsets.only(bottom: 12.h),
child: ExpansionTile(
leading: CircleAvatar(
backgroundColor: (breed['color'] as Color).withOpacity(0.1),
child: Icon(Icons.pets, color: breed['color'], size: 24.sp),
),
title: Text(breed['name'], style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16.sp)),
subtitle: Text('原产地: ${breed['origin']}'),
ExpansionTile点击可以展开显示更多内容。
leading放品种对应颜色的图标。
展开后的详情内容:
children: [
Padding(
padding: EdgeInsets.all(16.w),
child: Column(
children: [
_buildInfoRow(Icons.monitor_weight, '体重', breed['weight']),
_buildInfoRow(Icons.timer, '寿命', breed['lifespan']),
_buildInfoRow(Icons.psychology, '性格', breed['personality']),
_buildInfoRow(Icons.health_and_safety, '护理', breed['care']),
],
),
),
],
),
);
}
children是展开后显示的内容。
四行信息分别显示体重、寿命、性格、护理。
信息行组件
显示一行详情信息:
Widget _buildInfoRow(IconData icon, String label, String value) {
return Padding(
padding: EdgeInsets.symmetric(vertical: 6.h),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(icon, size: 18.sp, color: Colors.grey[600]),
SizedBox(width: 8.w),
SizedBox(
width: 50.w,
child: Text(label, style: TextStyle(color: Colors.grey[600], fontSize: 13.sp)),
),
Expanded(child: Text(value, style: TextStyle(fontSize: 13.sp))),
],
),
);
}
}
crossAxisAlignment设为start让内容顶部对齐。
Expanded让value文字可以换行。
ExpansionTile详解
可展开的列表项:
ExpansionTile(
leading: Widget, // 左侧图标
title: Widget, // 主标题
subtitle: Widget, // 副标题
children: [Widget], // 展开后的内容
)
点击标题区域可以展开或收起。
children是展开后显示的Widget列表。
ListView.builder
按需构建的列表:
ListView.builder(
padding: EdgeInsets.all(16.w),
itemCount: _breeds.length,
itemBuilder: (context, index) => _buildBreedCard(_breeds[index]),
)
只有可见的列表项才会被构建。
对于长列表,性能比ListView好很多。
CircleAvatar使用
圆形头像组件:
CircleAvatar(
backgroundColor: (breed['color'] as Color).withOpacity(0.1),
child: Icon(Icons.pets, color: breed['color'], size: 24.sp),
)
backgroundColor设置背景色。
child可以放任何Widget,这里放图标。
颜色处理
从Map中获取颜色:
breed['color'] as Color
Map的值是dynamic类型,需要转换为Color。
as关键字进行类型转换。
设置透明度:
(breed['color'] as Color).withOpacity(0.1)
withOpacity返回一个新的颜色。
0.1是10%的不透明度。
数据结构设计
用Map存储品种信息:
{
'name': '中华田园猫',
'origin': '中国',
'weight': '3-6 kg',
'lifespan': '12-20年',
'personality': '聪明、独立、适应力强',
'care': '易于照顾,抵抗力强',
'color': Colors.orange,
}
字符串作为key,值可以是任意类型。
这种结构灵活但不够类型安全。
更好的做法是定义类:
class CatBreed {
final String name;
final String origin;
final String weight;
final String lifespan;
final String personality;
final String care;
final Color color;
}
类的方式更类型安全。
但对于静态数据,Map也够用了。
Row布局技巧
信息行的布局:
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(...),
SizedBox(width: 8.w),
SizedBox(width: 50.w, child: Text(label)),
Expanded(child: Text(value)),
],
)
固定宽度的SizedBox让标签对齐。
Expanded让值文字占据剩余空间。
Card和ExpansionTile组合
卡片包裹可展开列表项:
Card(
margin: EdgeInsets.only(bottom: 12.h),
child: ExpansionTile(...),
)
Card提供阴影和圆角效果。
margin控制卡片之间的间距。
品种信息来源
这些品种信息的参考:
中华田园猫:中国本土猫,适应力强
英国短毛猫:圆脸大眼,性格温顺
美国短毛猫:虎斑花纹,活泼好动
布偶猫:蓝眼长毛,性格粘人
波斯猫:扁脸长毛,需要精心护理
暹罗猫:重点色,爱叫爱说话
缅因猫:大型猫,友善温和
折耳猫:耳朵折叠,有遗传疾病
俄罗斯蓝猫:银蓝色毛,低过敏
孟加拉猫:豹纹花色,精力旺盛
这些都是常见的猫咪品种。
每个品种都有自己的特点和护理要求。
图标选择
不同信息用不同图标:
Icons.monitor_weight // 体重
Icons.timer // 寿命
Icons.psychology // 性格
Icons.health_and_safety // 护理
图标让信息更直观。
Material Icons提供了丰富的图标选择。
小结
品种图鉴涉及的知识点:
- ListView.builder列表构建
- ExpansionTile可展开组件
- Map数据结构使用
- 颜色处理和类型转换
这个页面虽然简单,但展示了如何组织和展示静态数据。
欢迎加入OpenHarmony跨平台开发社区,一起交流Flutter开发经验:
https://openharmonycrossplatform.csdn.net
更多推荐



所有评论(0)