ANTD mobile源码分析 -- popover
最近的开发中要用到很多的各式各样的组件。但是发现ant design mobile(后面简称ANTDM)里很多的资源。于是就分析一下,学习学习。
ANTDM直接使用了typescript,没有用ES2015,不过这不会是障碍,反而是学习typescript的一个好机会。基本上可以学的开源项目里比这个好的也不多。
目录结构
Popover组件在:
|
|--components
|
|--popover
我们要分析的组件全部都在components这个目录下。
在这个目录里还包含tests, demo和style。里面分别存放测试代码、实例和样式。其他的文件包括*[component name]_native.tsx和[component name].txs以及对应的index.native.tsx和index.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的前两个参数是React和ReactNative。
回到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
});