现在我总结一下图像选择器的实现思路。
最核心的是引入ImagePicker.launchImageLibraryAsync()方法来打开图片选择器,然后围绕这个来写代码,首先我们创建一个异步函数pickimage,然后定义变量获取图片选择器返回的对象,然后判断是否选择。
然后由于选择图片的不同导致返回的对象url不同,根据这个思路我们就可以设置变量参数获取url然后传回给图片组件,然后图片组件呢多一个接受参数就是选择后的url,然后判断是否接收到了选择后的如果没有就按照默认的显示。相当于我们传回2个url参数有了选择的就显示选择的没有就显示默认的。 变量参数肯定数组结构获取usestate 更新状态方法这个套公式
export default function Index() { const pickImageAsync = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ['images'],
allowsEditing: true,
quality: 1,
});
if (!result.canceled) { console.log(result); }
else { alert('You did not select any image.'); } };
我总结一下模态框,首先创建模态框,无非就是两种布局,然后获取动态更新,比如设置showAppOptions布尔值来判断是否显示模态框,然后我们在图片被选择后可以更新showAppoptions来更新值为true或者点击一个按钮更新值为true 然后通过三元表达式,通过showappoptions的值来判断渲染前面布局还是后面的布局,前面布局的 样式我们依旧通过组件来设置,然后三个按钮,图标按钮,比如最左边的按钮点击关闭模态框,我们更新值为false就可以了。
然后给模态框中间的按钮添加一个表情符号选择器模式,跟图像选择器套公式,首先我们先不看表情,先默认创建选择器,当然没有内容。这套公式啊,我创建一个组件,完了我获取参数,无非就是打开的参数和关闭需要的函数,这都是设置布尔值,设置一个isvisible来控制是否打开表情选择器,然后关闭需要的函数无非点击更新传入isvisible的值为false,中间那个按钮点击为true,无非就是样式不同,比如按压的是一个图标,然后选择器有文本(自己设置的模态框标题),然后下一步就是给选择器添加选择的内容,我们添加一个组件,然后呢组件函数里面我们获取数据源,也就是定义一个数组获取我们需要的表情url,然后返回值里面用flatlist标签,然后data属性的值放入数据源就可以自动接收,然后用递归函数遍历数组所有的内容,然后用image标签自动一个个渲染到选择器中,然后再来个点击事件,获取你点击的标签的url,也就是我们传入的参数,方便我们选择表情后给表情进行动态效果添加,然后我们创建一个组件获取表情的url以及参数大小然后定义样式渲染到图片上
你在 index 页面传给 EmojiList 的 onSelect 函数就是 setPickedEmoji,这个函数在用户点击表情时会更新 pickedEmoji 的值。
(
{
onSelect(item);
onCloseModal();
}}>
)}
/>
总结一下手势,首先手势就是给所有要添加动画效果的页面添加gesturehandlertootview 包裹, 然后再需要添加动画的组件导入animated然后给要添加动画的标签元素比如image变成animated imager,然后添加点击手势,首先导入点击手势需要的方法,gesture usesharevalue withspring useanimatestyle 这些方法比如钩子usesharevalue 我们定义scaleimage通过usesharedvalue获取图片的当前的大小,然后定义doubletap获取gesture.tap点击事件然后定义.numberoftap(2),.onstart定义发生的函数功能,然后用useanimatestyle 设置发生函数功能时候的动画效果然后包裹组件包裹图片标签生成点击动画效果,这里的组件名是导入的gestureDetector 说明这个库自动识别吗?
GestureDetector 本身并不会自动识别任何东西,它需要你明确地将手势和动画逻辑连接起来。你需要通过手势方法(如 Gesture.Tap())来定义手势事件,GestureDetector 来处理这些手势,并通过 Animated 来实现动画效果。
const doubleTap = Gesture.Tap()
.numberOfTaps(2)
.onStart(() => {
if (scaleImage.value !== imageSize * 2) {
scaleImage.value = scaleImage.value * 2;
} else {
scaleImage.value = Math.round(scaleImage.value / 2);
}
});
const imageStyle = useAnimatedStyle(() => {
return {
width: withSpring(scaleImage.value),
height: withSpring(scaleImage.value),
};
});
const scaleImage = useSharedValue(imageSize); // 缩放用的变量
const translateX = useSharedValue(0); // 横向位移变量
const translateY = useSharedValue(0); // 纵向位移变量
const drag = Gesture.Pan().onChange(event => {
translateX.value += event.changeX;
translateY.value += event.changeY;
});
const containerStyle = useAnimatedStyle(() => {
return {
transform: [
{ translateX: translateX.value },
{ translateY: translateY.value },
],
};
});
const drag = Gesture.Pan().onChange(event => {
translateX.value += event.changeX;
translateY.value += event.changeY;
});
总结一下屏幕截图,首先引入截图库然后通过useref 方法获取更新方法imageref,然后给需要截图的标签设置ref然后用imageref更新获取,然后就可以添加截图组件,通过captureref获取对应ref的标签截图并返回给定义变量localurl然后用 await。 MediaLibrary.saveToLibraryAsync(localUri);方法获取并且本地下载,如果存在就下载不存就就报错。然后把函数组件作为参数给某个按钮然后点击实现功能
const [status, requestPermission] = MediaLibrary.usePermissions();
const imageRef = useRef(null);
const onSaveImageAsync = async () => {
try {
const localUri = await captureRef(imageRef, {
height: 440,
quality: 1,
});
await MediaLibrary.saveToLibraryAsync(localUri);
if (localUri) {
alert('Saved!');
}
} catch (e) {
console.log(e);
}
};
这就是expo文档我理解的大概思路,如果大家看到问题希望指出,我会非常非常感谢,评论即可,我每天会看。