RN for OpenHarmony AnimeHub项目实战 - 图片页
该代码实现了一个动漫图片展示页面,主要功能包括:1. 使用FlatList实现3列网格布局展示缩略图;2. 点击图片弹出Modal全屏预览大图;3. 通过API获取动漫图片数据。关键技术点:采用numColumns属性创建网格布局,使用Modal组件实现图片预览功能,并优化图片加载(缩略图用小图,预览用大图)。页面包含返回导航标题栏,支持触控操作关闭预览。整体设计采用等宽网格和半透明黑色背景的预览

动漫图片展示页面
页面简介
该页面专门用于展示动漫相关的官方图片资源,包括但不限于:
官方宣传海报
角色设定图
动画截图
特别活动图片
BD/DVD封面图
页面采用响应式设计,适配不同尺寸的移动设备屏幕。
页面功能详解
- 图片网格展示
采用3列瀑布流布局,确保图片展示整齐有序
每张图片自动按比例缩放填充容器
默认显示中等分辨率缩略图(约300×300像素)以优化加载速度
图片之间保持8px间距,视觉舒适
- 点击查看大图功能
点击任意缩略图可查看高清原图
大图加载时显示加载动画
支持手势缩放(通过第三方库实现)
双击放大/还原功能
- 图片预览模态框
全屏黑色半透明背景(透明度0.8)
图片居中显示,最大占屏幕宽度的90%和高度80%
点击任意位置或按返回键关闭预览
支持滑动切换查看相邻图片
核心代码实现
// src/screens/detail/AnimePicturesScreen.tsx
import React, { useEffect, useState } from ‘react’;
import {
View,
FlatList,
Image,
TouchableOpacity,
Modal,
Dimensions,
StyleSheet,
ActivityIndicator
} from ‘react-native’;
import { getAnimePictures } from ‘…/…/api/jikan’;
import { Header, Loading, EmptyState } from ‘…/…/components/common’;
const { width, height } = Dimensions.get(‘window’);
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: ‘#f5f5f5’
},
grid: {
padding: 8
},
imageWrapper: {
flex: 1,
margin: 4,
aspectRatio: 1,
borderRadius: 4,
overflow: ‘hidden’
},
thumbnail: {
width: ‘100%’,
height: ‘100%’
},
modalOverlay: {
flex: 1,
backgroundColor: ‘rgba(0,0,0,0.8)’,
justifyContent: ‘center’,
alignItems: ‘center’
},
fullImage: {
width: width * 0.9,
height: height * 0.8
},
loadingContainer: {
position: ‘absolute’,
justifyContent: ‘center’,
alignItems: ‘center’
}
});
export const AnimePicturesScreen = ({ navigation, route }: any) => {
const { animeId, title } = route.params;
const [pictures, setPictures] = useState([]);
const [selectedImage, setSelectedImage] = useState<string | null>(null);
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
loadData();
}, []);
const loadData = async () => {
try {
setIsLoading(true);
const res = await getAnimePictures(animeId);
setPictures(res.data || []);
} catch (error) {
console.error(‘加载图片失败:’, error);
} finally {
setIsLoading(false);
}
};
const renderItem = ({ item }) => (
<TouchableOpacity
style={styles.imageWrapper}
onPress={() => setSelectedImage(item.jpg.large_image_url)}
activeOpacity={0.7}
>
<Image
source={{ uri: item.jpg.image_url }}
style={styles.thumbnail}
resizeMode=“cover”
/>
);
if (isLoading) {
return ;
}
if (!pictures.length) {
return (
<Header title=“图片” subtitle={title} showBack onBack={() => navigation.goBack()} />
);
}
return (
<Header title=“图片” subtitle={title} showBack onBack={() => navigation.goBack()} />
<FlatList
data={pictures}
renderItem={renderItem}
keyExtractor={(item, index) => index.toString()}
numColumns={3}
contentContainerStyle={styles.grid}
initialNumToRender={12}
maxToRenderPerBatch={24}
windowSize={5}
/>
<Modal visible={!!selectedImage} transparent animationType="fade">
<TouchableOpacity
style={styles.modalOverlay}
onPress={() => setSelectedImage(null)}
activeOpacity={1}
>
{selectedImage && (
<Image
source={{ uri: selectedImage }}
style={styles.fullImage}
resizeMode="contain"
onLoadStart={() => setIsLoading(true)}
onLoadEnd={() => setIsLoading(false)}
/>
)}
{isLoading && (
<View style={styles.loadingContainer}>
<ActivityIndicator size="large" color="#fff" />
</View>
)}
</TouchableOpacity>
</Modal>
</View>
);
};
关键技术点深入解析
- 高性能网格布局优化
使用FlatList替代ScrollView,实现列表项的内存回收
配置initialNumToRender和maxToRenderPerBatch优化初始渲染性能
设置windowSize控制渲染区域外的预渲染项数
为每项设置稳定keyExtractor提升diff算法效率
- 图片加载最佳实践
缩略图使用image_url(中等分辨率)
预览图使用large_image_url(高分辨率)
添加加载状态指示器
实现渐进式加载策略
图片缓存机制(可集成react-native-fast-image)
- 模态框交互增强
添加点击穿透保护(activeOpacity=1)
加载状态反馈
平滑的动画过渡效果
内存优化处理
样式设计规范
网格系统:
列数:3列(手机)、4列(平板)
间距:4px
圆角:4px
图片规范:
缩略图:1:1宽高比
预览图:保持原始比例
最大尺寸:屏幕宽度的90%
颜色方案:
背景:浅灰(#f5f5f5)
模态背景:半透明黑(rgba(0,0,0,0.8))
加载指示器:白色
动效:
模态出现:淡入(300ms)
图片加载:渐显
性能优化建议
实现图片懒加载
添加图片缓存策略
使用WebP格式图片减少体积
实现预加载机制
添加错误边界处理
欢迎加入开源鸿蒙跨平台开发者社区:https://openharmonycrossplatform.csdn.net
获取更多React Native开发技巧和性能优化方案
更多推荐

所有评论(0)