由于前段时间写了一个React-Native的项目Mung,里面有一个图片浏览的功能,一般图片浏览都需要放大缩小和左右滑动,后来找了两个这方面比较好的控件react-native-gallery和react-native-image-viewer,但他们都有些问题,要不就卡顿,要不就滑动效果不会,这个其实跟React-Native触摸机制有关系,文章后面会提一下,后面就放弃了放大缩小的功能,实现左右滑动(这个比较简单),这几天有时间搞了下。
思路

- 没思路,滑动还是比较简单的,但手指缩放和滑动一起要做流畅的兼容,而且之前有人已经写了,他们都没写好(可能是RN版本的限制),所以先看资料在看看能不能选择一个进行优化一下实现更加流程的效果,所以选择优化现成的图片缩放控件,使其更加适合图片浏览。
- 2.说一下触摸机制的一点学习资料中文的 手势响应系统 、PanResponder中文的。
方法
- 本控件主要是为了实现图片缩放和左右滑动切换用的,大致说一下React-Native触摸机制问题。
- React-Native实现触摸相关的方法一般读书去实现PanResponder这个方法,感兴趣的可以点进去看一下,一般触摸一个控件是由上到下。在用户开始触摸的时候调用onStartShouldSetPanResponder(手指刚刚接触屏幕的瞬间),是否愿意成为响应者,放回true将接管触摸监听,还有一个就是onMoveShouldSetResponder如果View不是响应者,那么在每一个触摸点开始移动(没有停下也没有离开屏幕)时再询问一次:是否愿意响应触摸交互呢。其实还有很多,但现在只实现左右滑动(这里指的是用三方控件实现左右滑例如Swiper等)就会有问题,大致是,当你将onStartShouldSetPanResponder设置为true它将完全接管触摸,但有时候你可能是按下后左滑,这时你实现左右滑的控件将接受不到这个触摸,只有当手指抬起结束这次触摸才可以。如果你在onMoveShouldSetResponder设置为为true的话,将接受不到单机事件,这个可能会遇到的问题,解决办法在源码里,感兴趣的可以看下,缩放的算法直接使用的是react-native-image-viewer里面的。
效果

使用
yarn add react-native-zoom-view 或 npm install react-native-zoom-view
实现缩放和左右滑
import Swiper from 'react-native-swiper'
import ViewControl from 'react-native-zoom-view'
renderSwiperItemView() {
const imgs = [
'http://img1.ph.126.net/u1dVCkMgF8qSqqQLXlBFQg==/6631395420169075600.jpg',
'http://img2.ph.126.net/PqPdn4nhTSXTlPfDE_igJg==/6631322852401020356.jpg',
'http://img1.ph.126.net/Ta6-WaHwuYMSehnn6Xcmyg==/6631426206490316698.jpg',
'http://img0.ph.126.net/bCkBoPHS4d32mUJPqBIYrQ==/6631803338979839988.jpg',
'http://img2.ph.126.net/bkaOfRyDoyddXri0GjpWjA==/6630608169839463386.jpg',
];
return imgs.map((item,i)=>{
return (
<ViewControl
key={i}
cropWidth={width}
cropHeight={height}
imageWidth={width}
imageHeight={height}>
<Image
style={{
width:width,
height:height,
resizeMode: 'contain'
}}
source={{
uri:item
}}/>
</ViewControl>
)
})
}
render() {
return (
<Swiper
loop={false}
showsPagination={false}>
{this.renderSwiperItemView()}
</Swiper>
);
}
网友评论