[toc]
在 “我的” 页面中可以打开抽屉导航。
# 盖住APP
为了让抽屉导航能够把整个 APP(包含底部导航)都盖上,那么这个抽屉导航的代码,需要写在最外层组件中:
![](https://img.kancloud.cn/68/04/6804f1a1678ec79571dfce3404508d69_2656x1488.png)
# 整个 APP 整体向左滑动
为了让整个 APP 整体向左滑动,所以代码需要写在 “最外层” 组件中,控制整个 APP。
![](https://img.kancloud.cn/56/84/5684c532e7b2cb57dea7a944f74e46ba_2652x1460.png)
说明:向左移动可以使用 left 也可以使用 transform 实现,因为这个功能需要做成一个动画,而 transform 可以使用原生驱动动画,所以性能更好,所以这里选择使用 transform。
![](https://img.kancloud.cn/56/61/56615af3315207bfd9999c2a49c0cd92_1872x1488.png)
# 扩展知识点:布局时的层级
在 RN 中默认写在后面的组件会盖在前面的组件上,所以调整一个组件的层级:
1. 把高层级组件写在后面
2. 通过 `zIndex` 来设置层级
# 透明层
主 APP 上要有一个层盖上,当点击这个层时还能滑动 APP 回原位置:
![](https://img.kancloud.cn/8f/5b/8f5b2d934f6c298119cb8315e68a9976_2792x1302.png)
# 控制透明层的显示和隐藏
1. 定义变量
![](https://img.kancloud.cn/d9/9c/d99c40fe3a4c33eb0711b612b8d638d7_1312x434.png)
2. 通过这个变量判断组件是否显示(条件渲染)
![](https://img.kancloud.cn/84/c4/84c415177c53316cb6fbde3e887f40a7_1072x1182.png)
3. 在显示和隐藏抽屉时修改变量的值
![](https://img.kancloud.cn/45/6d/456d9d35758ccd72576b87f7f37d3cc5_958x530.png)
# 在子组件中控制这个抽屉动画
难点:抽屉的动画代码是写在最外层的父组件中的,如何在子组件“我的”这个页面中来调用?
解决办法:方法很多,其中一个思路是:数据在组件中的传递。
我们只要能把动画的代码传递到子组件中,在子组件中就可以调用了。
组件之间传递数据方法:
1. 一层一层的传,父-》子-》孙-》重孙-》。。。。 (优点:简单 缺点:层级多时很复杂)
2. 使用 redux(优点:组件间共享数据 缺点:需要安装并且代码稍微有些难度)
3. Context:React 中有一个 Context 技术,可以用来父向子孙组件共享数据。
综合来看使用 Context 来共享数据比较方便。
实际操作:
1. 在父组件中封装一个函数,用这个函数来执行动画
![](https://img.kancloud.cn/f9/4a/f94ad2823eef278629ab70c305350123_1144x652.png)
2. 通过 Context 组件把这个函数共享给所有子组件
![](https://img.kancloud.cn/32/76/3276b08e4490ec8a1cd408e3ad2404c1_1600x590.png)
3. 在子组件中就可以使用 Context 来得到这个函数并调用
![](https://img.kancloud.cn/dc/fa/dcfae5d1033f9fbae9d249a48fd1ad0e_1742x548.png)
![](https://img.kancloud.cn/4a/91/4a916fe309e8ef6069893de84f548b23_738x920.png)
# 扩展问题:函数写在组件中和写在组件外区别?
![](https://img.kancloud.cn/7b/af/7bafaa123ecd4a4175c28756b221cfc7_1368x1006.png)
所以一般需要操作数据,函数都写在组件中。
有什么办法能避免在组件中定义的函数在组件更新时重复定义吗?
答:使用 `useCallback` 来定义函数。
# 知识点总结:使用 Context 为子组件共享数据
1. 创建一个 Context
![](https://img.kancloud.cn/2b/f9/2bf96dca7c62dc2dca69ae61c547640c_1338x532.png)
2. 在父组件中引入并使用
引入
![](https://img.kancloud.cn/da/d4/dad4f7a496d9cf58927c09ca67b62dd3_1226x764.png)
把子组件套起来
![](https://img.kancloud.cn/d4/77/d477c9d8977b4228a4bce92526f36a9b_1426x578.png)
3. 在子组件中引入使用
![](https://img.kancloud.cn/91/ea/91ea406aa116d759b9f043de8b23f494_1458x824.png)
# 制作我的抽屉导航
## 问题一、无法写在子页面中
通过测试,发现如果把抽屉按钮写在子页面中无法定位到 整个 APP的右面
![](https://img.kancloud.cn/fd/8c/fd8c0989bb899e48220b25ff5c5b9d08_1662x1438.png)
所以这个抽屉的按钮虽然是显示在我的这个子页面中的,但代码还是要写在最外层的组件中,否则无法定位到整个 APP 的最右边:
![](https://img.kancloud.cn/0a/fd/0afd5a94dd7456c54fb0ff170db09c97_1824x1370.png)
## 调整抽屉导航的位置
因为整个 APP 向左滑动了 75% ,所以抽屉的宽度和位置也是 75%:
![](https://img.kancloud.cn/4c/4f/4c4fc2177bc38eea9e31ef6a565f2b96_1830x1432.png)
## 把原 Drawer 组件中的按钮拿过来
我们之前已经写了一个 Menu 组件,现在只要复制到这个框里即可:
1. 引入 Menu 组件
![](https://img.kancloud.cn/f0/62/f062f867c568d9dde084d6d65ac23824_1108x568.png)
2. 放到框中
![](https://img.kancloud.cn/c2/73/c2733c3c0a89d49ef195533bb9c72715_896x458.png)
现在存在一个问题,导航上的按钮不能点击。
原因:在屏幕之外的内容不能点击。
## 解决不能点击的问题:将导航按钮也放到屏幕中
1. 先把导航从主 APP 中拿出来
(目的:让主 APP 向左滑动时,导航不要随着滑动)
![](https://img.kancloud.cn/6e/c6/6ec6f1596b89069283fe8fd9bdf60692_1864x1184.png)
2. 把导航先放到外边去
![](https://img.kancloud.cn/50/35/5035fb5c2e678d4c68e05d3f0417b1a0_1556x1048.png)
3. 给抽屉导航也添加一个动画,让它滚动回屏幕中
这样就在屏幕中了,就可以点击了
![](https://img.kancloud.cn/df/94/df9487c4fb390d189a0cea5df6dd53b7_1666x1488.png)
# 通过滑动关闭抽屉导航
现在我们只能通过点击按钮来打开和关闭,但实际应该可以通过手势左右滑动就可以打开关闭抽屉 。
好了,接下来我们实现通过向右滑动来关闭抽屉。
在 RN 中提供了一个 `PanResponder` 组件可以实现左右滑动。
实际流程:
1. 创建一个监听左右滑动的组件
![](https://img.kancloud.cn/78/b8/78b897c37955f06ceffa9d5c53f62bc1_1072x356.png)
![](https://img.kancloud.cn/bc/0f/bc0f7933976fbce605dbc7fc1ee9a4d9_1462x872.png)
2. 把监听滑动的组件绑定到一个元素上
![](https://img.kancloud.cn/9e/bf/9ebf2ba6772d9654ba03f19b0c0edea2_1000x730.png)
# 知识点:PanResponder 组件介绍
![](https://img.kancloud.cn/a3/45/a3455d212bee69b8189c35c821598525_1948x1260.png)