需求
点击右上角下载icon,可以将当前图片下载并保存到本地相册。
下载的图片:
流程
下载图片的本质其实是,
固定需要下载的页面内容和样式 ===》将其放在当前页面不可见区域 ===》点击下载按钮 ===》穿一个ref给native,会自动拉起手机系统下载到本地相册
todo:native如何下载的话需要进一步再看一下
分析一下需要下载图片的样式:
- 头部logo,可选可不选
- 底部二维码和文案,固定的展示
- 中间部分是外部传进来的card部分
所以我们可以设置需要的props如下,
interface SnapshotProps {
backgroundImage: number;
cardNode: React.ReactNode;
bottomOpacity?: number; // 底部bottom透明度
isShowHeader?: boolean; // 是否需要头部logo,例如首页应该为false
viewRef: React.MutableRefObject<null>;
}
代码
import React, { memo } from 'react';
import { Image, ImageBackground, StyleSheet, Text, View } from 'react-native';
import Shopeepay from '../../assets/Shopeepay';
import QRCode from '../../assets/qrcode.png';
interface SnapshotProps {
backgroundImage: number;
cardNode: React.ReactNode;
bottomOpacity?: number; // 底部bottom透明度
isShowHeader?: boolean; // 是否需要头部logo,例如首页应该为false
viewRef: React.MutableRefObject<null>;
}
const getColorWithOpacity = (rgb: string, opacity: number): string =>
rgb.replace(')', `, ${opacity})`).replace('rgb', 'rgba');
const Snapshot = ({
backgroundImage,
bottomOpacity = 1,
cardNode,
isShowHeader = true,
viewRef,
}: SnapshotProps) => {
return (
<ImageBackground
style={styles.bgContainer}
source={backgroundImage}
ref={viewRef} // viewRef关键点
>
{isShowHeader && (
<View style={styles.headerView}>
<View style={styles.shopeepaySvg}>
<Shopeepay />
</View>
</View>
)}
<View style={styles.cardView}>{cardNode}</View> // 外部传进来的中间内容部分
<View
style={[
styles.bottomView,
{ // 背景透明度,如果设置Opacity属性的话,其所有子元素也会是透明或不透明状态
backgroundColor: getColorWithOpacity(
'rgb(233,78,43)',
bottomOpacity
),
},
]}
>
<View style={styles.leftView}>
<Text style={styles.title}>Scan to enter ShopeePay</Text>
<Text style={styles.subTitle}>Shopee.com/wrapup</Text>
</View>
<View style={styles.rightView}>
<Image style={styles.qrcodeImage} source={QRCode} />
</View>
</View>
</ImageBackground>
);
};
export default memo(Snapshot);
const styles = StyleSheet.create({
bgContainer: {
width: WINDOW_WIDTH,
height: WINDOW_HEIGHT,
},
headerView: {
justifyContent: 'center',
alignItems: 'center',
width: WINDOW_WIDTH,
height: 100,
},
shopeepaySvg: {
position: 'absolute',
top: 50,
},
cardView: {
flex: 1,
},
bottomView: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingHorizontal: 16,
height: 110,
},
leftView: {
marginLeft: 18,
},
title: {
fontSize: 16,
fontWeight: '500',
color: Colors.white,
},
subTitle: {
fontSize: 14,
marginTop: 4,
color: Colors.white,
},
rightView: {
flex: 1,
marginRight: 18,
alignItems: 'flex-end',
},
qrcodeImage: {
width: 80,
height: 80,
},
});
使用:
const onDownloadPress = async () => {
// ...
const resultFile = await captureViewToImage(viewRef); // 生成一个字符串,
if (resultFile) {
setImgUri(resultFile);
try {
await storeImageToDevice(rootTag, resultFile);
} catch (err) {
// ...
}
}
};
<Snapshot
viewRef={viewRef} // 关键点
backgroundImage={WrapUpBg}
cardNode={carouselData[carouselIndex]}
/>