yaofly2012 / note

Personal blog

Home Page:https://github.com/yaofly2012/note/issues

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

入坑RN

yaofly2012 opened this issue · comments

commented

Create native apps for Android, iOS, and more using React.

用JS可以开发媲美native用户体验的APP。

从此你是个native开发者了。

Issues

TouchableHighlightTouchableOpacity如何选择

几个概念

布局:

  • flex布局,只支持flexbox布局。相当于容器的display属性(其实没有display属性)有且只有一个枚举指flex
  • 单位
  • position
  • **Start, **End
  • **Vertical, **Horizontal

宽高

  • 没有默认值,需要显示指定(弹性,固定,百分比)?
  • 子组件撑父组件?

“声明”样式:
RN里应该是定义样式,只能通过style属性定义样式。样式定义是个普通的JS对象。

commented

Animation

背景

更新state方式的动画不可行的,性能太差。如果像ReactJs里那样可以直接操作DOM最好了。

RN提供两种动画系统:

  1. Animated
  2. LayoutAnimated

Animated

怎么理解?

Animated侧重于输入和输出之间的声明性关系,以及两者之间的可配置变换

Animated旨在以声明的形式来定义动画的输入与输出,在其中建立一个可配置的变化函数,然后使用start/stop方法来控制动画按顺序执行

触发方式:

  1. 基于时间

  2. 用户交互

  3. 以声明的形式来定义动画的输入与输出

  4. 配置变化函数

  5. 使用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);
};

AnimatedDiffClamp片段:

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计算基于两个规则:

  1. 输出值等于this._value = this._value + diff
  2. 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种)。

绑定/映射:

  1. mapped to this animated value

  2. Bind opacity to animated value

一个Animated Value可以绑定任意数量的其他属性/其他Animated Value。

Animated.Value实例对象可以绑定到多个style属性或者其他属性。

  1. 绑定指的是什么操作?
  2. 什么节点建立的映射?
  3. 其他属性是什么?

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

  1. 算术运算
  2. 插值(Interpolation)

插值(Interpolation)

所谓插值就是将一个区间值(inputRange)映射到一个新的区间值(outputRange )。

这里需要注意两点:

  1. 如何映射?
  2. 区间外的输入值如何处理?

详细参考interpolate Config

Issues:

  1. 区间片段数量必须一致?【是的,即inputRangeoutRange数组长度必须一致】
  2. 哪些字符串可以作为区间节点?【颜色,角度】

Animation type(驱动机制)

  1. Animated.timing
  2. Animated.spring
  3. Animated.decay

编排动画

串行,并行

跟踪动态值(Tracking dynamic values)

动画的中间值处理可以通过timing函数生成外,还可通过其他Animated.Value值生成。

如何建立映射

  1. toValue属性指定

跟踪手势(Tracking gestures

类似跟踪动态值,跟踪手势是指直接将滑动、滚动事件产生的变化映射Animated.Value值。

如何建立映射

  1. 同构方式声明

useNativeDriver

  1. 为什么使用useNativeDriver ?
  2. 什么情况下不能用useNativeDriver?
  • 非布局属性【Why】
  • 非冒泡事件【Why】

Using Native Driver for Animated

Issues/Concern

  1. Animated.event() with useNativeDriver option returns an object, not a function ? Why? 解决方案?

获取当前Value

⚠️⚠️非必需不要获取当前Value值 。毕竟只有Native知道当前值,要获取当前Value值(在JS层里)必然对性能造成影响。

可序列化与性能 TODO

Animated is designed to be fully serializable

可序列化

完全通过Plain Object声明动画。这样可将动画信息传给Native并让Native执行。

Issues:

  1. 每个动画只能有一个执行Driver

副作用

有时候可能会根据Animated.Value值执行一些操作。可以利用addListener绑定事件。

参考:

  1. Animation交互
  2. [译]详解React Native动画
  3. 系列:The Basics of React Native Animations
  4. 系列:Master React Native Animations
  5. React Native ScrollView animated header
  6. React Native collapsible navbar
  7. A Collapsing Navbar with Tabs in React Native
commented

样式 TODO

  1. flex布局
  2. style书写
  3. 单位

Density-independent pixels

  1. All dimensions in React Native are unitless, and represent density-independent pixels

  2. There is no universal mapping from points to physical units of measurement

Density-independent pixels ?

科普概念

  1. 屏幕尺寸(物理单位)
  2. 屏幕分辨率
  3. 屏幕像素密度
  4. px(屏幕像素点数,屏幕像素点尺寸也是有大小的差异(看技术了))
  5. dp

image

what dimension units are used in React Native?

Size Matters: How I used React Native to make my App look great on every device

Android 最全面的屏幕适配方案

响应式布局?TODO

https://www.npmjs.com/package/react-native-responsive-dimensions#why-responsive-dimensions

PK WEB CSS

不支持tansform-origin

解决方案:

  1. Anchor point for 3D Transform in React Native
  2. react-native-anchor-point
commented

利用FlatList实现sticky头部 TODO

头部渲染在哪里?
刚开始利用FlatList. ListHeaderComponent属性渲染头部。但是快速下拉页面时头部会出现空白区域(TODO 查询下原因)。尝试多种方式,还是放弃了。
目前将头部渲染在FlatList外部。

参考

Using React Native ScrollView to create a sticky header