需求
点击右上角下载icon,可以将当前图片下载并保存到本地相册。
下载的图片:
流程
下载图片的本质其实是,
固定需要下载的页面内容和样式 ===》将其放在当前页面不可见区域 ===》点击下载按钮 ===》穿一个ref给native,会自动拉起手机系统下载到本地相册
todo:native如何下载的话需要进一步再看一下
分析一下需要下载图片的样式:
- 头部logo,可选可不选
- 底部二维码和文案,固定的展示
- 中间部分是外部传进来的card部分
所以我们可以设置需要的props如下,
interface SnapshotProps {backgroundImage: number;cardNode: React.ReactNode;bottomOpacity?: number; // 底部bottom透明度isShowHeader?: boolean; // 是否需要头部logo,例如首页应该为falseviewRef: 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,例如首页应该为falseviewRef: 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 (<ImageBackgroundstyle={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> // 外部传进来的中间内容部分<Viewstyle={[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) {// ...}}
};<SnapshotviewRef={viewRef} // 关键点backgroundImage={WrapUpBg}cardNode={carouselData[carouselIndex]}
/>