项目概述
科技图库是一款基于鸿蒙系统(HarmonyOS)开发的高品质图片浏览应用,专注于展示精选科技主题图片。应用采用现代化的瀑布流布局,为用户提供流畅、直观的浏览体验,让科技之美尽收眼底。
主要功能
1. 瀑布流布局展示
- 自适应网格:采用双列瀑布流布局,根据图片原始比例自动调整显示大小
- 流畅滚动:优化的性能确保即使加载大量图片也能保持流畅的滚动体验
- 优雅加载:加载状态优雅展示,提供良好的用户反馈
2. 高清图片预览
- 全屏查看:点击任意缩略图即可进入全屏预览模式
- 智能加载:预览时显示加载进度,确保用户体验
- 容错机制:内置图片加载失败处理,确保应用稳定性
3. 用户友好界面
- 简洁设计:遵循现代设计理念,界面简洁直观
- 响应式交互:所有操作都有即时反馈,增强用户体验
- 优雅动效:精心设计的过渡效果,提升应用品质感
技术特点
鸿蒙原生开发
应用基于鸿蒙系统的ArkTS和ArkUI框架开发,充分利用了鸿蒙生态的先进特性:
- 声明式UI:使用ArkTS的声明式UI构建流畅界面
- 状态管理:采用@State等装饰器实现高效状态管理
- 自定义组件:通过@Component和@CustomDialog创建可复用组件
高效图片处理
- 智能缓存:优化图片加载和缓存策略,减少网络请求
- 延迟加载:实现图片延迟加载,提升应用启动速度
- 错误处理:完善的图片加载错误处理机制,提高应用稳定性
性能优化
- 资源管理:合理管理内存和网络资源,避免过度消耗
- 渲染优化:减少不必要的重绘,确保界面流畅响应
- 网络优化:智能处理网络请求,适应不同网络环境
用户体验亮点
- 即时反馈:所有用户操作都有清晰的视觉反馈
- 无缝浏览:从缩略图到大图预览的无缝切换体验
- 细节关注:从加载动画到错误提示,每个细节都经过精心设计
应用场景
科技爱好者的灵感来源
为科技爱好者提供高质量的科技主题图片,包括数据可视化、编程代码、高科技实验室、人工智能、未来城市等多种主题,激发创意灵感。
全部源码
import promptAction from '@ohos.promptAction';
// 定义图片数据接口
interface ImageItem {
url: string;
width: number;
height: number;
title: string;
}
// 图片预览对话框参数接口
interface ImagePreviewDialogParams {
imageUrl: string;
title: string;
onClose: () => void;
}
@Entry
@Component
struct Index {
// 模拟图片数据
private images: ImageItem[] = [
{
url: 'https://images.unsplash.com/photo-1518770660439-4636190af475?auto=format&fit=crop&w=800&h=1200&q=80',
width: 800,
height: 1200,
title: '科技数据可视化'
},
{
url: 'https://images.unsplash.com/photo-1526374965328-7f61d4dc18c5?auto=format&fit=crop&w=800&h=600&q=80',
width: 800,
height: 600,
title: '数字代码'
},
{
url: 'https://images.unsplash.com/photo-1550751827-4bd374c3f58b?auto=format&fit=crop&w=800&h=1000&q=80',
width: 800,
height: 1000,
title: '高科技实验室'
},
{
url: 'https://images.unsplash.com/photo-1558346490-a72e53ae2d4f?auto=format&fit=crop&w=800&h=1400&q=80',
width: 800,
height: 1400,
title: '人工智能概念'
},
{
url: 'https://images.unsplash.com/photo-1515879218367-8466d910aaa4?auto=format&fit=crop&w=800&h=800&q=80',
width: 800,
height: 800,
title: '编程代码特写'
},
{
url: 'https://images.unsplash.com/photo-1563770660941-20978e870e26?auto=format&fit=crop&w=800&h=1100&q=80',
width: 800,
height: 1100,
title: '未来城市'
},
{
url: 'https://images.unsplash.com/photo-1573164713988-8665fc963095?auto=format&fit=crop&w=800&h=900&q=80',
width: 800,
height: 900,
title: '智能手表科技'
},
{
url: 'https://images.unsplash.com/photo-1504384308090-c894fdcc538d?auto=format&fit=crop&w=800&h=700&q=80',
width: 800,
height: 700,
title: '网络安全概念'
},
{
url: 'https://images.unsplash.com/photo-1531297484001-80022131f5a1?auto=format&fit=crop&w=800&h=1300&q=80',
width: 800,
height: 1300,
title: '虚拟现实技术'
},
{
url: 'https://images.unsplash.com/photo-1488229297570-58520851e868?auto=format&fit=crop&w=800&h=1000&q=80',
width: 800,
height: 1000,
title: '数据中心'
},
{
url: 'https://images.unsplash.com/photo-1535223289827-42f1e9919769?auto=format&fit=crop&w=800&h=1200&q=80',
width: 800,
height: 1200,
title: '机器人技术'
},
{
url: 'https://images.unsplash.com/photo-1607252650355-f7fd0460ccdb?auto=format&fit=crop&w=800&h=900&q=80',
width: 800,
height: 900,
title: '量子计算概念'
}
]
@State selectedImage: string = ''
@State selectedTitle: string = ''
@State isLoading: boolean = false
dialogController: CustomDialogController = new CustomDialogController({
builder: ImagePreviewDialog({
imageUrl: this.selectedImage,
title: this.selectedTitle,
onClose: () => {
this.dialogController.close()
}
}),
alignment: DialogAlignment.Center,
customStyle: true,
autoCancel: false
})
aboutToAppear(): void {
// 页面加载时的初始化操作
this.isLoading = true
setTimeout(() => {
this.isLoading = false
}, 1000) // 模拟网络加载
}
build() {
Stack({ alignContent: Alignment.Center }) {
Column() {
// 页面标题
Row() {
Text('瀑布流图片展示')
.fontSize(24)
.fontWeight(FontWeight.Bold)
Blank()
Button('关于')
.fontSize(14)
.height(32)
.backgroundColor('#007DFF')
.borderRadius(16)
.onClick(() => {
promptAction.showToast({
message: '瀑布流布局展示与图片预览功能演示',
duration: 2000
})
})
}
.width('100%')
.padding({
top: 20,
bottom: 10,
left: 16,
right: 16
})
// 瀑布流布局
if (!this.isLoading) {
WaterFlow() {
ForEach(this.images, (item: ImageItem, index: number) => {
FlowItem() {
Column() {
Image(item.url)
.width('100%')
.aspectRatio(item.width / item.height)
.borderRadius(8)
.alt('加载中...')
.onError(() => {
// 图片加载失败处理
promptAction.showToast({
message: `图片 ${index + 1} 加载失败`,
duration: 2000
})
})
Text(item.title)
.fontSize(14)
.margin({ top: 4 })
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
}
.onClick(() => {
this.selectedImage = item.url
this.selectedTitle = item.title
this.dialogController.open()
})
}
.width('100%')
.margin(4)
})
}
.columnsTemplate('1fr 1fr') // 两列布局
.columnsGap(8) // 列间距
.rowsGap(12) // 行间距
.padding(12) // 内边距
.width('100%')
.layoutWeight(1) // 占满剩余空间
} else {
// 加载状态
LoadingProgress()
.width(50)
.height(50)
.color('#007DFF')
}
}
.width('100%')
.height('100%')
}
.width('100%')
.height('100%')
.backgroundColor('#f5f5f5')
}
}
@CustomDialog
struct ImagePreviewDialog {
private imageUrl: string = '';
private title: string = '';
private onClose: () => void = () => {
};
controller?: CustomDialogController;
@State isLoading: boolean = true;
constructor(params: ImagePreviewDialogParams) {
super();
this.imageUrl = params.imageUrl;
this.title = params.title;
this.onClose = params.onClose;
}
build() {
Stack({ alignContent: Alignment.Center }) {
Column() {
// 标题栏
Row() {
Text(this.title)
.fontSize(18)
.fontWeight(FontWeight.Medium)
.fontColor('#FFFFFF')
Blank()
Button() {
Image($r('sys.media.ohos_ic_public_cancel'))
.width(24)
.height(24)
.fillColor('#FFFFFF')
}
.backgroundColor('rgba(0,0,0,0)')
.width(36)
.height(36)
.onClick(() => {
this.controller?.close()
this.onClose()
})
}
.width('100%')
.padding(16)
.backgroundColor('rgba(0,0,0,0.5)')
// 图片展示
Stack({ alignContent: Alignment.Center }) {
Image(this.imageUrl)
.width('100%')
.objectFit(ImageFit.Contain)
.layoutWeight(1)
.onComplete(() => {
this.isLoading = false
})
.onError(() => {
this.isLoading = false
promptAction.showToast({
message: '图片加载失败',
duration: 2000
})
})
if (this.isLoading) {
LoadingProgress()
.width(50)
.height(50)
.color('#FFFFFF')
}
}
.width('100%')
.layoutWeight(1)
}
.width('100%')
.height('100%')
}
.width('100%')
.height('100%')
.backgroundColor('#000000')
.onClick(() => {
// 点击背景关闭
this.controller?.close()
this.onClose()
})
}
}
原文链接:https://code.ifrontend.net/archives/626,转载请注明出处。
评论0