sunshine-anycall

ANTD mobile源码分析 -- popover

最近的开发中要用到很多的各式各样的组件。但是发现ant design mobile(后面简称ANTDM)里很多的资源。于是就分析一下,学习学习。

ANTDM直接使用了typescript,没有用ES2015,不过这不会是障碍,反而是学习typescript的一个好机会。基本上可以学的开源项目里比这个好的也不多。

目录结构

Popover组件在:

|
|--components
  |
  |--popover

我们要分析的组件全部都在components这个目录下。

在这个目录里还包含tests, demostyle。里面分别存放测试代码、实例和样式。其他的文件包括*[component name]_native.tsx[component name].txs以及对应的index.native.tsxindex.tsx,方便外部引入组件。

计算点击组件的位置

这个是最核心的问题了!

实现React Native的弹出菜单,需要达到在界面上的某个可点击组件上点击了之后,就可以在被点击的组件紧挨着的下方出现一个菜单(其他的计算,比如弹出菜单在左下、右下,左上,右上的位置计算暂时不提)。

用户点击了哪个组件(按钮),哪个按钮的下面就出现一个菜单(View)。这就需要确定点击组件的位置。

我们看一下index.native.tsx这个文件。文件里基本上没几行代码,直接看render方法里返回的是MenuContext等。也就是,这个文件没实现什么pop over需要的什么东西。都在import里了:

import Menu, { MenuContext, MenuOptions, MenuOption, MenuTrigger }from 'react-native-menu';

所以ANTDM的源码分析到此为止。

我们要跳到react-native-menu。我们分析代码的方式就是无限递归,一直找到实现功能的代码为止。那么我们就可以分析react-native-menu了。

react-native-menu

这个项目的写法也是很不同。用的是比较老的ES5的React版本。github地址在这里

这个项目里很多的文件,各位可以后面慢慢看。我们来看makeMenuContext.js

在这个项目里,除了index.js之外都是叫做makeXXX.js。里面都是HOC的实现方式。而且更加Trick的是HOC的前两个参数是ReactReactNative

回到makeMenuContext.js,在openMenu()这个方法里就有实现的方式。这就是我们寻找代码递归跳出的地方。我们来看一下实现方式:

openMenu(name) {
  const handle = ReactNative.findNodeHandle(this._menus[name].ref);
  UIManager.measure(handle, (x, y, w, h, px, py) => {
    this._menus[name].measurements = { x, y, w, h, px, py };

    this.setState({
      openedMenu: name,
      menuOptions: this._makeAndPositionOptions(name, this._menus[name].measurements),
      backdropWidth: this._ownMeasurements.w
    });

    this._activeMenuHooks = this._menus[name];
    this._activeMenuHooks && this._activeMenuHooks.didOpen();
  });
},

这里使用了UIManager,来自:

  const {
    UIManager,
    TouchableWithoutFeedback,
    ScrollView,
    View,
    BackHandler
  } = ReactNative

用现代一点的写法的话就是:import { UIManager } from 'react-native';

使用的时候是这么用的:

  const handle = ReactNative.findNodeHandle(this._menus[name].ref);
  UIManager.measure(handle, (x, y, w, h, px, py) => {
    // x, y, width, height, pageX, pageY
  });

分类:

技术点:

相关文章: