首页 > 其他分享 >bottom tap新增一个自定义icon,点击弹出Modal

bottom tap新增一个自定义icon,点击弹出Modal

时间:2024-04-02 15:14:07浏览次数:28  
标签:tap Modal 自定义 bottom Screen component state Tab 组件

我想实现的效果是这样的:

 

    

注意:Modal的背景还是其他的tab,并没有变化,等Modal消失后Screen还是原来的screen。

Solution:

      因为中间的自定义图标按钮需要有一部分在Tab中,所以还是把icon作为tab中的一个screen的,于是就借用:tabBarButton 来实现,参考了一些文章,都是把Modal封装为一个组件,然后把Tab.screen的component设置为这个组件,结果怎么调试都有问题,不是这有问题就是那有问题。后来改变了下思路,把Model放置在平行于Tab.Navigator的同级元素上解决了这个问题。代码如下:

       

  // 设置Model是否显示的state,这个state需要放在tab同级组件中,不能放到Model组件中
  const [isAddActivityVisible, setIsAddActivityVisible] = useState(false);
  const clickAddActivity = () => { setIsAddActivityVisible(true); };
  const hideAddActivity = () => { setIsAddActivityVisible(false); };
  // 借助Tab的listeners方法来做,因为需要preventDefault()来阻止screen跳转
<>
</Tab.Navigator>
   <Tab.Screen
        name="AddActivity"
        listeners={
          ({ navigation }) => ({
            tabPress: (e) => {
              // Prevent default action
              e.preventDefault();
              clickAddActivity();
            },
          })
        }
        options={{
            tabBarButton: (props) => (
              <TouchableOpacity {...props}>
                <Icon icon="add1" size={58} />
              </TouchableOpacity>
            )
          }} >
      {() => <></>}
      ......
  </Tab.Navigator>
   // 放在和Tab.Navigator同级
   <AddActivityModal isModalVisible={isAddActivityVisible} onHide={hideAddActivity} />
</>

     而Modal组件自己定义即可。

     

interface ModalProps {
  isModalVisible: boolean;
  onHide: () => void;
}

export const AddActivityModal : FC<ModalProps> = 
  ({isModalVisible, onHide}) => {
  React.useEffect(() => {
    console.log('AddActivityModal did mount,isModalVisible:'+isModalVisible);
  }, []);

  return (
    <Modal isVisible={isModalVisible} onHide={onHide} onBackdropPress={onHide}>
      <Modal.Container>
        <View style={styles.modal}>
        <Modal.Header title="LogRocket is fab!" />
        <Modal.Body>
        <Text style={styles.text}>Agree to continue with this guide</Text>
        </Modal.Body>
        <Modal.Footer>
        <Button title="I agree" onPress={onHide} />
        </Modal.Footer>
        </View>
      </Modal.Container>
    </Modal>
  );
}

 ----------------------------------------------------------------------------------------------

尝试过的有问题的方案:

1.  尝试把Modal的component放在Tab.Screen中。参考:https://medium.com/@my.maithi/react-native-navigation-add-custom-button-in-the-middle-of-tabbar-6c390201a2bb ,这个方案把圆形button和Modal放到一个Screen component中,其中也包括了state。

     问题在于:中间圆形button的样式总是调不好。

2.  把中间圆形Button放在Tab.Screen中,用TabBarButton来控制,这种方案如下:

    <Tab.Screen
        name="AddActivity"
        options={
          ({ navigation }) => ({
            tabBarButton: (props) => (
              <TouchableOpacity
                onPress={() => console.log("1111")}
                {...props}>
                <Icon icon="add1" size={58} />
              </TouchableOpacity>
            ),
          })
        } >
      {() => <AddActivityModal isModalVisible={isAddActivityVisible} onHide={hideAddActivity} />}
  </Tab.Screen>

        问题有:a) AddActivityModal 是Tab.Screen的child component, 根据react推荐做法,需要把state从child component中提升到父类的compoenent中  b) 在TouchableOpacity中点击onPress方法,总是不能加载child component,好像这个onPress方法阻碍了系统默认的behavior(转到childScreen),没有很好的解决办法 c) 即便b的问题解决了,点击中间的button的时候会转到Modal的Screen,但是当Modal窗口取消后整个Screen就变空白了,因为navigation转到modal的screen了,modal隐藏后就是空白了。

       所以这两个方案都有问题,思路不对。

需要注意的技术点:

      1)当有Parent Component和其Child Component时候,不要尝试直接在parent组件中直接调用child组件的方法,这不是推荐的做法,推荐的做法是用prop来传递值,由child component来做处理。当然在特殊情况下也可以做到这一点,主要用Ref, CreateRef, UseRef,参考:https://refine.dev/blog/react-useref-hook-and-ref/#using-the-useref-hook-in-an-application , https://blog.logrocket.com/use-forwardref-react/

     2)当父component中有个button,点击后想要change 子component中的state变化,这种情况下,根据推荐做法,需要把state lift提升,参考:https://legacy.reactjs.org/docs/lifting-state-up.html 

标签:tap,Modal,自定义,bottom,Screen,component,state,Tab,组件
From: https://www.cnblogs.com/saaspeter/p/18110340

相关文章

  • 按指定规则(自定义)拆分PDF文件
    #-*-coding:utf-8-*-'''创建文件夹:1.txt:为拆分规则文件名,(在文件夹中写入1-4try,就是把1-4截取下来放在文件夹为try.pdf的文件夹下)m.pdf:为拆分文件名称split.py为文件的名称'''fromPyPDF2importPdfReader,PdfWriter#PDF文件分割defsplit_pdf():  t......
  • Quill文档(三):构建自定义模块
    Quill作为编辑器的核心优势在于其丰富的API和强大的定制能力。当您在Quill的API之上实现功能时,将其组织为一个模块可能会很方便。为了本指南的目的,我们将逐步介绍一种构建单词计数器模块的方法,这是许多文字处理器中常见的功能。注意在内部,模块是Quill的许多功能的组织方......
  • EL虚拟化表格 用h函数自定义表头并且指定插槽
    第一次使用el-table-v2,需要实现点击表头弹框来展示数据,官方文档中只有tsx的写法,没有使用h函数的写法,因此记录一下先看下最终的效果以下是部分代码import{ElButton,ElRadio,ElTooltip,ElPopover }from'element-plus'; //columns是一个数组,里面的值为每一列的配置......
  • 【docker】Dockerfile自定义镜像
           ......
  • Higress 基于自定义插件访问 Redis
    作者:钰诚简介基于wasm机制,Higress提供了优秀的可扩展性,用户可以基于Go/C++/Rust编写wasm插件,自定义请求处理逻辑,满足用户的个性化需求,目前插件已经支持redis调用,使得用户能够编写有状态的插件,进一步提高了Higress的扩展能力。文档在插件中调用Redis[1]中提供了......
  • vue 自定义tabs 样式的组件
    大家应该都用过tabs不同状态显示不同的列表 这种东西其实可以自己封装的其实是很简单的做一个这样简单的筛选组件 这样的跟tabs的效果一样上代码<template><divclass="switch-container"><divclass="box"><divclass="box-item"......
  • MogDB/openGauss 自定义snmptrapd告警信息
    MogDB/openGauss自定义snmptrapd告警信息在实际使用中,默认的报警规则信息并不能很好的满足snmp服务端的需求,需要定制化报警信息,这里以添加ip为例,看似一个简单的将IP一行信息单独在报警展示出来,涉及到的配置文件修改还是挺多的。修改prometheus.yml文件首先需要修改......
  • 自定义类型:【结构体】
    我们知道C语言中有许多的类型,比如char,short,int等等类型。像是这些C语言本身就支持的类型叫做内置类型,但是有一些复杂对象,只有这些类型是完全不够的。比如人,或者一本书。那么我们就可以自己定义一些类型来实现。一.结构体的基础知识1.结构体的创建与初始化结构是一些值的集合......
  • Vue自定义指令directive(主要是钩子函数及其参数)
    Vue自定义指令directive(主要是钩子函数及其参数):https://blog.csdn.net/weixin_46037781/article/details/119637729?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171194263116777224467854%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request......
  • PyQt:【重磅干货】实现一个自定义样式的窗口(比如去掉边框、改变标题位置、窗口按钮样式
    如果想突破PyQt自带窗口的样式限制,比如同时去掉窗口的边框、改变边框、改变标题位置、窗口控制按钮等等,那就需要实现一个自定义样式的窗口,本文教你如何实现先来看看PyQt创建窗口的默认样式:再看看一个自定义样式的窗口:可以看到,这里示例的自定义窗口去掉了窗口的边框、改......