React?Native?Popup怎么實現

蝸牛 互聯網技術資訊 2022-05-18 57 0

這篇文章主要介紹“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怎么實現”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注蝸牛博客網站,小編會繼續努力為大家帶來更多實用的文章!

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

評論

日本韩欧美一级A片在线观看