入坑RN
yaofly2012 opened this issue · comments
Create native apps for Android, iOS, and more using React.
用JS可以开发媲美native用户体验的APP。
从此你是个native开发者了。
Issues
TouchableHighlight
和TouchableOpacity
如何选择
几个概念
布局:
flex
布局,只支持flexbox布局。相当于容器的display
属性(其实没有display
属性)有且只有一个枚举指flex
。- 单位
position
**Start
,**End
**Vertical
,**Horizontal
宽高:
- 没有默认值,需要显示指定(弹性,固定,百分比)?
- 子组件撑父组件?
“声明”样式:
RN里应该是定义样式,只能通过style
属性定义样式。样式定义是个普通的JS对象。
Animation
背景
更新state方式的动画不可行的,性能太差。如果像ReactJs里那样可以直接操作DOM最好了。
RN提供两种动画系统:
Animated
LayoutAnimated
Animated
怎么理解?
Animated
侧重于输入和输出之间的声明性关系,以及两者之间的可配置变换
Animated
旨在以声明的形式来定义动画的输入与输出,在其中建立一个可配置的变化函数,然后使用start/stop
方法来控制动画按顺序执行
触发方式:
-
基于时间
-
用户交互
-
以声明的形式来定义动画的输入与输出
-
配置变化函数
-
使用
start/stop
方法来控制动画按顺序执行。
可动画组件:
函数diffClamp(AnimatedValue, min, max)
Create a new Animated value that is limited between 2 values. It uses the difference between the last value so even if the value is far from the bounds it will start changing when the value starts getting closer again.
(value = clamp(value + diff, min, max))
看来RN官方文档解释实在不知道diffClamp(AnimatedValue, min, max)
是干嘛的。在深入了解前可以先了解CSSclamp(min, val, max)
函数功能。diffClamp
是限制Animated.Value
的范围,不过计算规则稍稍麻烦些:OutputAnimatedValue = clamp(OutputAnimatedValue + diff, min, max)
(diff = CurrentInputAnimatedValue - LastInputAnimatedValue),公式有点抽象,直接贴源码:
diffClamp
const diffClamp = function (
a: AnimatedNode,
min: number,
max: number,
): AnimatedDiffClamp {
return new AnimatedDiffClamp(a, min, max);
};
export default class AnimatedDiffClamp extends AnimatedWithChildren {
constructor(a: AnimatedNode, min: number, max: number) {
super();
this._a = a;
this._min = min;
this._max = max;
this._value = this._lastValue = this._a.__getValue();
}
__getValue(): number {
const value = this._a.__getValue();
const diff = value - this._lastValue;
this._lastValue = value;
this._value = Math.min(Math.max(this._value + diff, this._min), this._max);
return this._value;
}
}
核心就是constructor
和__getValue
方法。输出值this._value
计算基于两个规则:
- 输出值等于
this._value = this._value + diff
- 把
this._value
限制在[min, max]
之间,即:
- 如果
this._value
小于min
,则this._value = min
; - 如果
this._value
大于max
,则this._value = max
。
举个🌰,假设当前Input是0,对于Animated.diffClamp(Input, 0, 10)
的输出:
当前Input | 上次Input | Diff(当前Input - 上次Input) | 上次Output | 当前Output | |
---|---|---|---|---|---|
1 | 0 | - | - | - | 0 |
2 | 2 | 0 | 2 | 0 | 2 |
3 | 8 | 2 | 6 | 2 | 8 |
4 | 10 | 8 | 2 | 8 | 10 |
5 | 11 | 10 | 1 | 10 | 10 |
6 | 20 | 11 | 9 | 10 | 10 |
7 | 15 | 20 | -5 | 10 | 5 |
第5,6步因为大于最大值10,所以被限制为10。
一般用于实现可折叠导航栏。
Animated.Value
是什么
Standard value for driving animations
驱动动画的标准值(即动画过程中变化的值)。一个Animated.Value
可以以同步方式驱动多个属性,但一次只能由一种机制驱动(目前3种)。
绑定/映射:
-
mapped to this animated value
-
Bind opacity to animated value
一个Animated Value可以绑定任意数量的其他属性/其他Animated Value。
Animated.Value
实例对象可以绑定到多个style属性或者其他属性。
- 绑定指的是什么操作?
- 什么节点建立的映射?
- 其他属性是什么?
Animated.Value
实例对象作为state还是成员变量比较合适?
看文档Demo里都是作为成员变量使用,并且只实例化一次。文档里有说明:
- 对于函数组件:
Don't modify the animated value directly. You can use the useRef Hook to return a mutable ref object. This ref object's current property is initialized as the given argument and persists throughout the component lifecycle.
- 对于类组件:
Don't modify the animated value directly. It is usually stored as a state variable in class components.
类组件为啥要用state, 可以用作成员变量吗?【可以,本质是要求避免re-render时重新创建】
组合Animated.Value
利用一个或者多个Animated.Value
产生新的Animated.Value
。
- 算术运算
- 插值(Interpolation)
插值(Interpolation)
所谓插值就是将一个区间值(inputRange
)映射到一个新的区间值(outputRange
)。
这里需要注意两点:
- 如何映射?
- 区间外的输入值如何处理?
Issues:
- 区间片段数量必须一致?【是的,即
inputRange
和outRange
数组长度必须一致】 - 哪些字符串可以作为区间节点?【颜色,角度】
Animation type(驱动机制)
Animated.timing
Animated.spring
Animated.decay
编排动画
串行,并行
跟踪动态值(Tracking dynamic values)
动画的中间值处理可以通过timing函数生成外,还可通过其他Animated.Value
值生成。
如何建立映射
toValue
属性指定
跟踪手势(Tracking gestures)
类似跟踪动态值,跟踪手势是指直接将滑动、滚动事件产生的变化映射Animated.Value
值。
如何建立映射
- 同构方式声明
useNativeDriver
- 为什么使用
useNativeDriver
? - 什么情况下不能用
useNativeDriver
?
- 非布局属性【Why】
- 非冒泡事件【Why】
Using Native Driver for Animated
Issues/Concern
获取当前Value
可序列化与性能 TODO
Animated is designed to be fully serializable
可序列化
完全通过Plain Object声明动画。这样可将动画信息传给Native并让Native执行。
Issues:
- 每个动画只能有一个执行Driver
副作用
有时候可能会根据Animated.Value
值执行一些操作。可以利用addListener
绑定事件。
参考:
样式 TODO
- flex布局
- style书写
- 单位
Density-independent pixels
-
All dimensions in React Native are unitless, and represent density-independent pixels
-
There is no universal mapping from points to physical units of measurement
Density-independent pixels ?
科普概念
- 屏幕尺寸(物理单位)
- 屏幕分辨率
- 屏幕像素密度
- px(屏幕像素点数,屏幕像素点尺寸也是有大小的差异(看技术了))
- dp
what dimension units are used in React Native?
Size Matters: How I used React Native to make my App look great on every device
响应式布局?TODO
https://www.npmjs.com/package/react-native-responsive-dimensions#why-responsive-dimensions
PK WEB CSS
不支持tansform-origin
解决方案:
利用FlatList
实现sticky头部 TODO
头部渲染在哪里?
刚开始利用FlatList. ListHeaderComponent
属性渲染头部。但是快速下拉页面时头部会出现空白区域(TODO 查询下原因)。尝试多种方式,还是放弃了。
目前将头部渲染在FlatList
外部。