中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

React?Native?Popup怎么實現

發布時間:2022-05-18 13:54:51 來源:億速云 閱讀:227 作者:iii 欄目:開發技術

這篇文章主要介紹“React Native Popup怎么實現”,在日常操作中,相信很多人在React Native Popup怎么實現問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”React Native Popup怎么實現”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

React Native 官方提供了 Modal 組件,但 Modal 是屬于全屏的彈出層,當 Modal 顯示時,操作區域只有 Modal 里的元素,而且焦點會被 Modal 劫持。雖然移動端不常見,但有些場景還是希望可以用輕量級一點的 Popup

在 React Native 里,元素的層級是不可以被穿透的,子元素無論如何都不能遮擋父元素。所以選擇了在頂層添加 Popup,設置絕對定位,顯示時根據指定元素來動態調整 Popup 的位置的方案。

具體實現

Popup 會有顯示或隱藏兩種狀態,使用一個 state 來控制。

const Component = () => {
  const [visible, setVisible] = useState(false);
  
  return (
    <>
      {visible && <></>}
    </>
  );
};

Popup 的 屬于視圖類組件,UI 結構包括:

  • 一個作為容器的 View,由于 iOS 有劉海,所以在 iOS 上需要使用 SafeAreaView 來避免被劉海遮擋。同時添加一個點擊事件監聽當點擊時關閉 Popup

  • 一個指向目標對象的三角形。

  • 一個包裹內容的 View

由于 Popup 的位置和內容是動態的,所以需要兩個 state 存儲相關數據。

  • 一個存儲位置相關的 CSS。

  • 一個存儲動態內容。

const Component = ({ style, ...other }) => {
  const [visible, setVisible] = useState(false);
  const [popupStyle, setPopupStyle] = useState({});
  const [content, setContent] = useState(null);
  
  const onPress = useCallback(() => {
    setVisible(false);
  }, []);
  
  return (
    <>
      {visible &&
        createElement(
          Platform.OS === 'ios' ? SafeAreaView : View,
          {
            style: {
              ...styles.popup,
              ...popupStyle,
            },
          },
          <TouchableOpacity onPress={onPress}>
            <View style={styles.triangle} />
            <View style={{ ...styles.content, ...style }} {...other}>
              {content}
            </View>
          </TouchableOpacity>,
        )}
    </>
  );
};

const styles = StyleSheet.create({
  popup: {
    position: 'absolute',
    zIndex: 99,
    shadowColor: '#333',
    shadowOpacity: 0.12,
    shadowOffset: { width: 2 },
    borderRadius: 4,
  },
  triangle: {
    width: 0,
    height: 0,
    marginLeft: 12,
    borderLeftWidth: 8,
    borderLeftColor: 'transparent',
    borderRightWidth: 8,
    borderRightColor: 'transparent',
    borderBottomWidth: 8,
    borderBottomColor: 'white',
  },
  content: {
    backgroundColor: 'white',
  },
});

因為是全局的 Popup,所以選擇了一個全局變量來提供 Popup 相關的操作方法。

如果全局 Popup 不適用,可以改成在需要時插入 Popup 并使用 ref 來提供操作方法。

目標元素,動態內容和一些相關的可選配置都是在調用 show 方法時通過參數傳入的,

useEffect(() => {
  global.$popup = {
    show: (triggerRef, render, options = {}) => {
      const { x: offsetX = 0, y: offsetY = 0 } = options.offset || {};
      triggerRef.current.measure((x, y, width, height, left, top) => {
        setPopupStyle({
          top: top + height + offsetY,
          left: left + offsetX,
        });
        setContent(render());
        setVisible(true);
      });
    },
    hide: () => {
      setVisible(false);
    },
  };
}, []);

完整代碼

import React, {
  createElement,
  forwardRef,
  useState,
  useEffect,
  useCallback,
} from 'react';
import PropTypes from 'prop-types';
import {
  View,
  SafeAreaView,
  Platform,
  TouchableOpacity,
  StyleSheet,
} from 'react-native';

const Component = ({ style, ...other }, ref) => {
  const [visible, setVisible] = useState(false);
  const [popupStyle, setPopupStyle] = useState({});
  const [content, setContent] = useState(null);

  const onPress = useCallback(() => {
    setVisible(false);
  }, []);

  useEffect(() => {
    global.$popup = {
      show: (triggerRef, render, options = {}) => {
        const { x: offsetX = 0, y: offsetY = 0 } = options.offset || {};
        triggerRef.current.measure((x, y, width, height, left, top) => {
          setPopupStyle({
            top: top + height + offsetY,
            left: left + offsetX,
          });
          setContent(render());
          setVisible(true);
        });
      },
      hide: () => {
        setVisible(false);
      },
    };
  }, []);

  return (
    <>
      {visible &&
        createElement(
          Platform.OS === 'ios' ? SafeAreaView : View,
          {
            style: {
              ...styles.popup,
              ...popupStyle,
            },
          },
          <TouchableOpacity onPress={onPress}>
            <View style={styles.triangle} />
            <View style={{ ...styles.content, ...style }} {...other}>
              {content}
            </View>
          </TouchableOpacity>,
        )}
    </>
  );
};

Component.displayName = 'Popup';

Component.prototype = {};

const styles = StyleSheet.create({
  popup: {
    position: 'absolute',
    zIndex: 99,
    shadowColor: '#333',
    shadowOpacity: 0.12,
    shadowOffset: { width: 2 },
    borderRadius: 4,
  },
  triangle: {
    width: 0,
    height: 0,
    marginLeft: 12,
    borderLeftWidth: 8,
    borderLeftColor: 'transparent',
    borderRightWidth: 8,
    borderRightColor: 'transparent',
    borderBottomWidth: 8,
    borderBottomColor: 'white',
  },
  content: {
    backgroundColor: 'white',
  },
});

export default forwardRef(Component);

使用方法

  • 在入口文件頁面內容的末尾插入 Popup 元素。

    // App.jsx
    import Popup from './Popup';
    
    const App = () => {
      return (
        <>
          ...
          <Popup />
        </>
      );
    };
  • 使用全局變量控制。

    // 顯示
    $popup.show();
    // 隱藏
    $popup.hide();

到此,關于“React Native Popup怎么實現”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

惠州市| 印江| 阳高县| 元谋县| 灌南县| 台安县| 铜陵市| 仁化县| 周宁县| 周至县| 犍为县| 唐海县| 怀集县| 商洛市| 全南县| 十堰市| 昌宁县| 准格尔旗| 光山县| 惠来县| 安西县| 曲周县| 建昌县| 自治县| 阿荣旗| 崇礼县| 马龙县| 湄潭县| 景谷| 湾仔区| 广州市| 郁南县| 阜阳市| 吉安市| 延寿县| 巴彦县| 三江| 廉江市| 静乐县| 监利县| 赤城县|