轩云 發表於 2019-7-2 10:53:00

react-native-gesture-handler 使用

<p>安装</p>
<pre><code>yarn add react-native-gesture-handler
</code></pre>
<p>link到原生项目中</p>
<pre><code>react-native link react-native-gesture-handler
</code></pre>
<h2 id="为什么写这个文档">为什么写这个文档</h2>
<p>官方文档看的难受。React Native Gesture Handler 官网文档</p>
<h2 id="为什么要使用这个库">为什么要使用这个库</h2>
<p><strong>更加的流畅、可靠。</strong></p>
<p>react-native自带的PanResponder手势监视器由JS响应器系统控制而react-native-gesture-handler是在UI线程中识别和跟踪手势。</p>
<p>若使用RN官方提供的手势管理在与发生在主线程上的触摸交互(如iOS滑块或任何滚动视图)时,经常会遇到问题。<mark>由于主线程必须同步决定JS或滚动视图是否应该成为响应器,而JS只能异步响应并不能立即拒绝Native事件的响应,导致手势操作被这些Native组件劫持。</mark></p>
<p><em>ps: 上面提到的JS不能立即拒绝Native事件的响应对应PanResponder中的onPanResponderTerminationRequest方法,当该方法返回false时表示拒绝其他组件响应当前的手势。</em></p>
<p>问题场景示例:</p>
<ol>
<li>使用react-native-scroll-tab-view组件作为导航,左右切换视图。</li>
<li>在react-native-scroll-tab-view内嵌套了Slider组件或者其他使用PanResponder手势监视器实现了某些手势操作。</li>
<li>使用时常常会出现在这些子组件做滑动操作时,触发了react-native-scroll-tab-view组件的滑动的问题。</li>
</ol>
<p>详情react-native项目中的这个issue:How to stopPropagation touch event</p>
<p>我解决这个问题过程: 如何在RN的可滚动组件内设置一个禁止滚动的区域</p>
<h2 id="组件与方法说明">组件与方法说明</h2>
<p><strong>组件通用属性、方法</strong>Common handler properties</p>
<pre><code>enabled:是否响应手势操作。
shouldCancelWhenOutside:当前手势离开当前组件区域时是否进入CANCELLED或FAILD状态。
simultaneousHandlers
waitFor:等待其他事件结束时才响应手势操作
hitSlop:可以控制视图区域的哪个部分来开始识别手势。与View组件的hitSlop类似
onGestureEvent:手势ACTIVE状态时执行的回调
onHandlerStateChange:手势状态改变时的回调
</code></pre>
<p><strong>事件参数</strong></p>
<p>onHadlerStateChange与onGestureEvent回调的参数event(主要用到的就是nativeEvent属性)</p>
<pre><code class="language-js">
//event的属性声明
interface event {
    nativeEvent: nativeEvent
    //...
}

//nativeEvent的属性声明
interface nativeEvent {
    absoluteX: number //相对于根视图,指针的当前位置的X坐标(当放置多个手指时的手指或前导指针)。
    absoluteY: number //相对于根视图,指针的当前位置的Y坐标(当放置多个手指时的手指或前导指针)。
    handlerTag: number
    numberOfPointers: number //表示当前放置在屏幕上的指针(手指)的数量。
    state: number //手势处理程序的当前状态
    translationX: number //手势开始到目前为止在水平方向上的移动距离。它与PanResponder中的dx类似
    translationY: number //手势开始到目前为止在垂直方向上的移动距离。
    velocityX: number //水平移速
    velocityY: number //垂直移速
    x: number //当前手势位置相对于附加PanGestureHandler的视图的X
    y: number //当前手势位置相对于附加PanGestureHandler的视图的Y
}
</code></pre>
<p>手势操作过程中,react-native-gesture-handler提供Handlers组件的State会不断变化,开发者根据State来响应不同状态下的操作。详情查看Handler State</p>
<h2 id="与panresponder对照">与PanResponder对照</h2>
<table>
<thead>
<tr>
<th>说明</th>
<th>PanGestureHandler</th>
<th>PanResponder</th>
</tr>
</thead>
<tbody>
<tr>
<td>是否声明成为触摸手势响应者或是否声明成为移动手势的响应者</td>
<td>-</td>
<td>onStartShouldSetPanResponder ,onMoveShouldSetPanResponder</td>
</tr>
<tr>
<td>触摸手势开始</td>
<td>onHadlerStateChange, State.BEGAN</td>
<td>onPanResponderGrant</td>
</tr>
<tr>
<td>手势移动过程中执行的回调</td>
<td>onHadlerStateChange, onGestureEvent, State.ACTIVE</td>
<td>onPanResponderMove</td>
</tr>
<tr>
<td>手势释放</td>
<td>onHadlerStateChange, State.END或State.FAILED</td>
<td>onPanResponderRelease</td>
</tr>
<tr>
<td>是否将响应手势的操作交给其他组件</td>
<td>-</td>
<td>onPanResponderTerminationRequest</td>
</tr>
<tr>
<td>手势操作被其他组件或事件打断后的回调</td>
<td>-</td>
<td>onPanResponderTerminate</td>
</tr>
</tbody>
</table>
<p>使用对比:</p>
<p>PanGestureHandler</p>
<pre><code class="language-js">import {PanGestureHandler, State} from 'react-native-gesture-handler'

//...

&lt;PanGestureHandler
    onHadlerStateChange = ({nativeEvent}) =&gt; {
      switch (nativeEvent.state) {
          case State.UNDETERMINED:
            console.log('等待手势')
            break;
          case State.BEGAN:
            console.log('手势开始')
            break;
          case State.CANCELLED:
            console.log('手势取消')
            break;
          case State.ACTIVE:
            console.log('手势活跃')
            break;
          case State.END:
            console.log('手势结束')
            break;
          case State.FAILED:
            console.log('失败')
            break;
          default:
            console.log('其他')
            break;
      }
    }
    onGestureEvent = ({ nativeEvent }) =&gt; {
   
    }
&gt;
    &lt;Animated.View
      //...
    &gt;
    &lt;/Animated.View&gt;
&lt;/PanGestureHandler&gt;
</code></pre>
<p>PanResponder</p>
<pre><code class="language-js">import {PanResponder} from 'react-native'

&lt;Animated.View
    {
      ...PanResponder.create({
            onStartShouldSetPanResponder: this._handleStartShouldSetPanResponder,
            onMoveShouldSetPanResponder: this._handleMoveShouldSetPanResponder,
            onPanResponderGrant: this._handlePanResponderGrant,
            onPanResponderMove: this._handlePanResponderMove,
            onPanResponderRelease: this._handlePanResponderEnd,
            onPanResponderTerminationRequest: this._handlePanResponderRequestEnd,
            onPanResponderTerminate: this._handlePanResponderEnd,
      }).panHandlers
    }
&gt;
&lt;/Animated.View&gt;
</code></pre>


</div>
<div id="MySignature" role="contentinfo">
    行为影响状态,状态影响视图<br><br>
来源:https://www.cnblogs.com/foxNike/p/11119188.html
頁: [1]
查看完整版本: react-native-gesture-handler 使用