我模仿 Facebook 的 Paper 应用构建了一个开闭卡片的轮播效果作为技术演示.它使用了 React Native 及其动画库.
当人们听到 React Native 后第一反应会觉得它运行缓慢.这是因为一般人会去这样解释 React Native: "它允许你通过 Javascript 构建你的应用程序",而人们会认为浏览器中运行的 JavaScript 性能并不够好.
但事实是,它采用的全部都是原生界面元素.但你通过 React Native 构建界面时, 每次都会实例化 Android 和 iOS 的原生 UI.因此,相比于比较沉重的 DOM 结构它是相当请轻量的.
下面一段介绍:我是如何着手构建类似 Facebook 的 Paper 应用的交互效果的. 我们可以放大和缩小轮播图,在动画进行的时候,我们也可以停止它.
先来看看它是什么样子:
上面的屏幕截图,是从我所构建的 App 中截出来的. 左边是当前缩小的卡片列表.您可以滑动它们.您也可以把它拉起来,让它们变成全屏. 现在你可以在全屏状态下滑动卡片,一个接一个. 我们来与下面 Facebook Paper应用的交互模型来进行比较.
我们以实例化两个状态变量开始.一个用于存储 pan 值,另一个存储动画进度:从0到1.这一进展变量是基于 pan 值进行插值.
let pan = new Animated.ValueXY();
this.state = {
pan: pan,
dockAnimation: pan.y.interpolate({
inputRange: [-300, 0],
outputRange: [0, 1],
})
}
现在,我们需要创建一个 panResponder. 这是一个复杂的手势操控的概念,它判断什么时候应该激活手势以及们完成事件的各种方法.在我们的例子中,我们要在手势正在进行和结束对它进行跟踪.
this._panResponder = PanResponder.create({
onStartShouldSetPanResponder: (evt, gestureState) => true,
onStartShouldSetPanResponderCapture: (evt, gestureState) => true,
onMoveShouldSetPanResponder: (evt, gestureState) => true,
onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,
onPanResponderGrant: () => {},
onPanResponderMove: Animated.event([null, {dx: this.state.pan.x, dy: this.state.pan.y}]),
onPanResponderRelease: (evt, gestureState) => {
// dragging stopped, animate the item to the correct position
}
})
在实际代码中可以看到看到 onPanResponderRelease 块的全部实现.它做的很简单:决定用户是否已经拖远远,并切换 state 的值.如果是,绘制这个动画.
transform: [{
scale: this.state.dockAnimation.interpolate({
inputRange: [0, 1],
outputRange: [1, 0.5],
})
}
多种变换被以 ListView 的 style 的方式应用. 我已经用 scale 变换作为例子展示了,再一次,我们使用插值来控制动画.
<AnimatedListView
style={this.getListViewStyle()}
{...this._panResponder.panHandlers}
/>
最后,styles 和 panResponder 的 panResponder 都被绑定到了 ListView. 需要注意的是在我们创建了一个一个组合式的 ListView: AnimatedListView,这样的动画库可以从样式对象解析出动画的值.
这就是我们需要为动画做的所有事情!剩下的就是使用 Flex 布局来构建那些漂亮的卡片.Jason Brown 写了一本有关React Native动画库的好书:http://browniefed.com/react-n...
我在 Github 上共享了所有的代码,你可以自由修改它!
paramaggarwal/rn-paper-interface
<iframe src="https://player.vimeo.com/vide... width="640" height="1137" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
目前,我只在iOS上运行过.但是你可以尝试在 Android 上运行,并在 github 上打开一个 PR. 我没有用过任何的 iOS 特定的 API, 所以理论上,它应该在 Android 上工作.
作者信息
原文作者:Param Aggarwal
原文链接:http://t.cn/RtnSJwA
翻译自力谱宿云 LeapCloud旗下MaxLeap团队_UX成员:Jason
中文首发地址:https://blog.maxleap.cn/archi...
译者简介:MaxLeap UX 组负责人,负责前端开发,客户端/部分服务端 SDK 开发及开发者用户体验优化相关工作. 持续关注新技术,热爱产品, 热衷全栈/全端开发. 曾供职于搜狐搜狐武汉研究院,后投身 MaxLeap致力于为开发者提供快速高效的开发体验.
相关文章
ReactJS 开发过程中的一些使用心得
在 React Web 和 原生 App 中共享代码
React Native 一周年回顾
React.js 最佳实践(2016)
作者往期作品:
在 React Web 和 原生 App 中共享代码
React.js 最佳实践(2016)
活动预告
报名链接:http://t.cn/Rt9ooRw
欢迎关注微信公众号:MaxLeap_yidongyanfa