<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        React Native仿美團下拉菜單的實例代碼

        來源:懂視網 責編:小采 時間:2020-11-27 22:33:13
        文檔

        React Native仿美團下拉菜單的實例代碼

        React Native仿美團下拉菜單的實例代碼:本文介紹了React Native仿美團下拉菜單的實例代碼,最近也在學習React Native,順便分享給大家 在很多產品中都會涉及到下拉菜單選擇功能,用的最好的當屬美團了,其效果如下: 要實現上面的效果,在原生中比較好做,直接使用PopWindow組件即可。
        推薦度:
        導讀React Native仿美團下拉菜單的實例代碼:本文介紹了React Native仿美團下拉菜單的實例代碼,最近也在學習React Native,順便分享給大家 在很多產品中都會涉及到下拉菜單選擇功能,用的最好的當屬美團了,其效果如下: 要實現上面的效果,在原生中比較好做,直接使用PopWindow組件即可。

        本文介紹了React Native仿美團下拉菜單的實例代碼,最近也在學習React Native,順便分享給大家

        在很多產品中都會涉及到下拉菜單選擇功能,用的最好的當屬美團了,其效果如下:

        要實現上面的效果,在原生中比較好做,直接使用PopWindow組件即可。如果使用React Native開發上面的效果,需要注意幾個問題:

        1、 在下拉的時候有動畫過度效果;

        2、下拉菜單出現后點擊菜單項,菜單項可選擇,并觸發對應的事件;

        3、下拉菜單中的項目可以配置;

        要實現彈框效果,我們馬上回想到使用Model組件,而要繪制打鉤圖標和下拉三角,我們首先想到使用ART實現,當然選擇使用圖標也是可以的。例如使用ART繪制對勾的代碼如下:

        const Check = ()=>{
         return (
         <Surface
         width={18}
         height={12}
         >
         <Group scale={0.03}>
         <Shape
         fill={COLOR_HIGH}
         d={`M494,52c-13-13-33-13-46,0L176,324L62,211c-13-13-33-13-46,0s-13,33,0,46l137,136c6,6,15,10,23,10s17-4,23-10L494,99
         C507,86,507,65,494,52z`}
         />
         </Group>
         </Surface>
         );
        }

        下拉動畫的實現上,需要使用Animated。例如,背景顏色變化需要使用Animated.timing。

         this.state.fadeInOpacity, 
         {
         toValue: value, 
         duration : 250, 
         }

        運行效果:

        本示例設計三個文件:導航欄FoodActionBar.js,下拉彈框TopMenu.js和文件主類FoodView.js。

        FoodActionBar.js

        /**
         * https://github.com/facebook/react-native
         * @flow 首頁的標題欄
         */
        
        import React, {Component} from 'react';
        import {Platform, View, Dimensions, Text, StyleSheet, TouchableOpacity, Image} from 'react-native';
        import px2dp from '../util/Utils'
        
        const isIOS = Platform.OS == "ios"
        const {width, height} = Dimensions.get('window')
        const headH = px2dp(isIOS ? 64 : 44)
        
        export default class FoodActionBar extends Component {
        
         constructor(props) {
         super(props);
         this.state = {
         showPop: false,
         }
         }
        
        
         renderHeader() {
         return (
         <View style={styles.headerStyle}>
         <TouchableOpacity style={styles.action} >
         <Image style={styles.scanIcon}/>
         </TouchableOpacity>
         <TouchableOpacity style={styles.searchBar}>
         <Image source={require('../images/ic_search.png')} style={styles.iconStyle}/>
         <Text style={{fontSize: 13, color: "#666", marginLeft: 5}}>輸入商家名、品類和商圈</Text>
         </TouchableOpacity>
         <TouchableOpacity style={styles.action} onPress={() => { this.setState({ showPop: !this.state.showPop }) }}>
         <Image style={styles.scanIcon}
         source={require('../images/icon_address.png')}/>
         </TouchableOpacity>
         </View>
         )
         }
        
         render() {
         return (
         <View>
         {this.renderHeader()}
         </View>
         );
         }
        }
        
        const styles = StyleSheet.create({
         headerStyle: {
         backgroundColor: "#ffffff",
         height: headH,
         paddingTop: px2dp(isIOS ? 20 : 0),
         flexDirection: 'row',
         alignItems: 'center',
         },
         searchBar: {
         flex:1,
         height: 30,
         borderRadius: 19,
         backgroundColor:'#e9e9e9',
         marginLeft: 10,
         flexDirection: 'row',
         justifyContent: 'flex-start',
         alignItems: 'center',
         alignSelf: 'center',
         paddingLeft: 10,
         },
         text: {
         fontSize: 16,
         color: '#ffffff',
         justifyContent: 'center',
         },
         iconStyle: {
         width: 22,
         height: 22,
         },
         action: {
         flexDirection: 'row',
         justifyContent: 'center',
         alignItems: 'center',
         marginLeft:10,
         marginRight:10
         },
         scanIcon: {
         width: 28,
         height: 28,
         alignItems: 'center',
         },
         scanText: {
         fontSize: 14,
         color: '#ffffff',
         justifyContent: 'center',
         alignItems: 'center',
         },
        });
        
        

        TopMenu.js

        /**
         * Sample React Native App
         * https://github.com/facebook/react-native
         * @flow
         */
        
        import React, {Component} from 'react';
        import {
         AppRegistry,
         StyleSheet,
         Animated,
         ScrollView,
         Dimensions,
         PixelRatio,
         Text,
         TouchableWithoutFeedback,
         TouchableHighlight,
         ART,
         View
        } from 'react-native';
        
        const {Surface, Shape, Path, Group} = ART;
        
        const {width, height} = Dimensions.get('window');
        
        const T_WIDTH = 7;
        const T_HEIGHT = 4;
        
        const COLOR_HIGH = '#00bea9';
        const COLOR_NORMAL = '#6c6c6c';
        
        const LINE = 1 / PixelRatio.get();
        
        class Triangle extends React.Component {
        
         render() {
        
         var path;
         var fill;
         if (this.props.selected) {
         fill = COLOR_HIGH;
         path = new Path()
         .moveTo(T_WIDTH / 2, 0)
         .lineTo(0, T_HEIGHT)
         .lineTo(T_WIDTH, T_HEIGHT)
         .close();
         } else {
         fill = COLOR_NORMAL;
         path = new Path()
         .moveTo(0, 0)
         .lineTo(T_WIDTH, 0)
         .lineTo(T_WIDTH / 2, T_HEIGHT)
         .close();
         }
        
         return (
         <Surface width={T_WIDTH} height={T_HEIGHT}>
         <Shape d={path} stroke="#00000000" fill={fill} strokeWidth={0}/>
         </Surface>
         )
         }
        }
        
        const TopMenuItem = (props) => {
         const onPress = () => {
         props.onSelect(props.index);
         }
         return (
         <TouchableWithoutFeedback onPress={onPress}>
         <View style={styles.item}>
         <Text style={props.selected ? styles.menuTextHigh : styles.menuText}>{props.label}</Text>
         <Triangle selected={props.selected}/>
         </View>
         </TouchableWithoutFeedback>
         );
        };
        
        const Subtitle = (props) => {
         let textStyle = props.selected ?
         [styles.tableItemText, styles.highlight, styles.marginHigh] :
         [styles.tableItemText, styles.margin];
        
         let rightTextStyle = props.selected ? [styles.tableItemText, styles.highlight] : styles.tableItemText;
        
         let onPress = () => {
         props.onSelectMenu(props.index, props.subindex, props.data);
         }
        
         return (
         <TouchableHighlight onPress={onPress} underlayColor="#f5f5f5">
         <View style={styles.tableItem}>
         <View style={styles.row}>
         {props.selected && <Check />}
         <Text style={textStyle}>{props.data.title}</Text>
         </View>
         <Text style={rightTextStyle}>{props.data.subtitle}</Text>
         </View>
         </TouchableHighlight>
         );
        };
        
        const Title = (props) => {
         let textStyle = props.selected ?
         [styles.tableItemText, styles.highlight, styles.marginHigh] :
         [styles.tableItemText, styles.margin];
        
         let rightTextStyle = props.selected ? [styles.tableItemText, styles.highlight] : styles.tableItemText;
        
        
         let onPress = () => {
         props.onSelectMenu(props.index, props.subindex, props.data);
         }
        
         return (
         <TouchableHighlight onPress={onPress} underlayColor="#f5f5f5">
         <View style={styles.titleItem}>
         {props.selected && <Check />}
         <Text style={textStyle}>{props.data.title}</Text>
         </View>
         </TouchableHighlight>
         );
        };
        
        const Check = () => {
         return (
         <Surface
         width={18}
         height={12}
         >
         <Group scale={0.03}>
         <Shape
         fill={COLOR_HIGH}
         d={`M494,52c-13-13-33-13-46,0L176,324L62,211c-13-13-33-13-46,0s-13,33,0,46l137,136c6,6,15,10,23,10s17-4,23-10L494,99
         C507,86,507,65,494,52z`}
         />
         </Group>
         </Surface>
         );
        }
        
        
        
        export default class TopMenu extends Component {
        
         constructor(props) {
         super(props);
         let array = props.config;
         let top = [];
         let maxHeight = [];
         let subselected = [];
         let height = [];
         //最大高度
         var max = parseInt((height - 80) * 0.8 / 43);
        
        
         for (let i = 0, c = array.length; i < c; ++i) {
         let item = array[i];
         top[i] = item.data[item.selectedIndex].title;
         maxHeight[i] = Math.min(item.data.length, max) * 43;
         subselected[i] = item.selectedIndex;
         height[i] = new Animated.Value(0);
         }
        
        
         //分析數據
         this.state = {
         top: top,
         maxHeight: maxHeight,
         subselected: subselected,
         height: height,
         fadeInOpacity: new Animated.Value(0),
         selectedIndex: null
         };
        
        
         }
        
        
         componentDidMount() {
        
         }
        
         createAnimation = (index, height) => {
         return Animated.timing(
         this.state.height[index],
         {
         toValue: height,
         duration: 250
         }
         );
         }
        
         createFade = (value) => {
         return Animated.timing(
         this.state.fadeInOpacity,
         {
         toValue: value,
         duration: 250,
         }
         );
         }
        
        
         onSelect = (index) => {
         if (index === this.state.selectedIndex) {
         //消失
         this.hide(index);
         } else {
         this.setState({selectedIndex: index, current: index});
         this.onShow(index);
         }
         }
        
         hide = (index, subselected) => {
         let opts = {selectedIndex: null, current: index};
         if (subselected !== undefined) {
         this.state.subselected[index] = subselected;
         this.state.top[index] = this.props.config[index].data[subselected].title;
         opts = {selectedIndex: null, current: index, subselected: this.state.subselected.concat()};
         }
         this.setState(opts);
         this.onHide(index);
         }
        
        
         onShow = (index) => {
        
         Animated.parallel([this.createAnimation(index, this.state.maxHeight[index]), this.createFade(1)]).start();
         }
        
        
         onHide = (index) => {
         //其他的設置為0
         for (let i = 0, c = this.state.height.length; i < c; ++i) {
         if (index != i) {
         this.state.height[i].setValue(0);
         }
         }
         Animated.parallel([this.createAnimation(index, 0), this.createFade(0)]).start();
        
         }
        
         onSelectMenu = (index, subindex, data) => {
         this.hide(index, subindex);
         this.props.onSelectMenu && this.props.onSelectMenu(index, subindex, data);
         }
        
        
         renderList = (d, index) => {
         let subselected = this.state.subselected[index];
         let Comp = null;
         if (d.type == 'title') {
         Comp = Title;
         } else {
         Comp = Subtitle;
         }
        
         let enabled = this.state.selectedIndex == index || this.state.current == index;
        
         return (
         <Animated.View key={index} pointerEvents={enabled ? 'auto' : 'none'}
         style={[styles.content, {opacity: enabled ? 1 : 0, height: this.state.height[index]}]}>
         <ScrollView style={styles.scroll}>
         {d.data.map((data, subindex) => {
         return <Comp
         onSelectMenu={this.onSelectMenu}
         index={index}
         subindex={subindex}
         data={data}
         selected={subselected == subindex}
         key={subindex}/>
         })}
         </ScrollView>
         </Animated.View>
         );
         }
        
         render() {
         let list = null;
         if (this.state.selectedIndex !== null) {
         list = this.props.config[this.state.selectedIndex].data;
         }
         console.log(list);
         return (
         <View style={{flex: 1}}>
         <View style={styles.topMenu}>
         {this.state.top.map((t, index) => {
         return <TopMenuItem
         key={index}
         index={index}
         onSelect={this.onSelect}
         label={t}
         selected={this.state.selectedIndex === index}/>
         })}
         </View>
         {this.props.renderContent()}
         <View style={styles.bgContainer} pointerEvents={this.state.selectedIndex !== null ? "auto" : "none"}>
         <Animated.View style={[styles.bg, {opacity: this.state.fadeInOpacity}]}/>
         {this.props.config.map((d, index) => {
         return this.renderList(d, index);
         })}
         </View>
         </View>
         );
         }
        }
        
        const styles = StyleSheet.create({
        
         scroll: {flex: 1, backgroundColor: '#fff'},
         bgContainer: {position: 'absolute', top: 40, width: width, height: height},
         bg: {flex: 1, backgroundColor: 'rgba(50,50,50,0.2)'},
         content: {
         position: 'absolute',
         width: width
         },
        
         highlight: {
         color: COLOR_HIGH
         },
        
         marginHigh: {marginLeft: 10},
         margin: {marginLeft: 28},
        
        
         titleItem: {
         height: 43,
         alignItems: 'center',
         paddingLeft: 10,
         paddingRight: 10,
         borderBottomWidth: LINE,
         borderBottomColor: '#eee',
         flexDirection: 'row',
         },
        
         tableItem: {
         height: 43,
         alignItems: 'center',
         paddingLeft: 10,
         paddingRight: 10,
         borderBottomWidth: LINE,
         borderBottomColor: '#eee',
         flexDirection: 'row',
         justifyContent: 'space-between'
         },
         tableItemText: {fontWeight: '300', fontSize: 14},
         row: {
         flexDirection: 'row'
         },
        
         item: {
         flex: 1,
         flexDirection: 'row',
         alignItems: 'center',
         justifyContent: 'center',
         },
         menuTextHigh: {
         marginRight: 3,
         fontSize: 13,
         color: COLOR_HIGH
         },
         menuText: {
         marginRight: 3,
         fontSize: 13,
         color: COLOR_NORMAL
         },
         topMenu: {
         flexDirection: 'row',
         height: 40,
         borderTopWidth: LINE,
         borderTopColor: '#bdbdbd',
         borderBottomWidth: 1,
         borderBottomColor: '#f2f2f2'
         },
        
        });
        
        

        主類FoodView.js:

        /**
         * Sample React Native App
         * https://github.com/facebook/react-native
         * @flow
         */
        
        import React, {Component} from 'react';
        import {
         AppRegistry,
         StyleSheet,
         TouchableOpacity,
         Dimensions,
         Text,
         View
        } from 'react-native';
        const {width, height} = Dimensions.get('window');
        
        import FoodActionBar from "./pop/FoodActionBar";
        import Separator from "./util/Separator";
        import TopMenu from "./pop/TopMenu";
        
        
        const CONFIG = [
         {
         type:'subtitle',
         selectedIndex:1,
         data:[
         {title:'全部', subtitle:'1200m'},
         {title:'自助餐', subtitle:'300m'},
         {title:'自助餐', subtitle:'200m'},
         {title:'自助餐', subtitle:'500m'},
         {title:'自助餐', subtitle:'800m'},
         {title:'自助餐', subtitle:'700m'},
         {title:'自助餐', subtitle:'900m'},
         ]
         },
         {
         type:'title',
         selectedIndex:0,
         data:[{
         title:'智能排序'
         }, {
         title:'離我最近'
         }, {
         title:'好評優先'
         }, {
         title:'人氣最高'
         }]
         }
        ];
        
        
        export default class FoodView extends Component {
        
         constructor(props){
         super(props);
         this.state = {
         data:{}
         };
         }
        
         renderContent=()=>{
         return (
         <TouchableOpacity >
         <Text style={styles.text}>index:{this.state.index} subindex:{this.state.subindex} title:{this.state.data.title}</Text>
         </TouchableOpacity>
         );
         // alert(this.state.data.title)
         };
        
         onSelectMenu=(index, subindex, data)=>{
         this.setState({index, subindex, data});
         };
        
         render() {
         return (
         <View style={styles.container}>
         <FoodActionBar/>
         <Separator/>
         <TopMenu style={styles.container} config={CONFIG} onSelectMenu={this.onSelectMenu} renderContent={this.renderContent}/>
         </View>
         );
         }
        }
        
        const styles = StyleSheet.create({
         container: {
         flex: 1,
         width:width,
         backgroundColor: '#F5FCFF',
         },
         text: {
         fontSize:20,
         marginTop:100,
         justifyContent: 'center',
         alignItems: 'center',
        
         },
        
        });
        
        

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        React Native仿美團下拉菜單的實例代碼

        React Native仿美團下拉菜單的實例代碼:本文介紹了React Native仿美團下拉菜單的實例代碼,最近也在學習React Native,順便分享給大家 在很多產品中都會涉及到下拉菜單選擇功能,用的最好的當屬美團了,其效果如下: 要實現上面的效果,在原生中比較好做,直接使用PopWindow組件即可。
        推薦度:
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 美女无遮挡拍拍拍免费视频 | 亚洲啪啪免费视频| 久久久青草青青亚洲国产免观 | 99久久综合国产精品免费| 亚洲成人在线免费观看| 91免费在线播放| 亚洲sss综合天堂久久久| 久久久www成人免费毛片| 亚洲看片无码在线视频| 日本19禁啪啪无遮挡免费动图| 亚洲精品久久无码| 免费观看四虎精品国产永久| 国产精品免费视频观看拍拍| 国产亚洲精品美女久久久| 永久在线免费观看| 亚洲中文字幕无码爆乳app| 免费看国产精品麻豆| 久久WWW免费人成—看片| 久久精品国产亚洲AV麻豆~| **真实毛片免费观看| 亚洲精品无AMM毛片| 亚洲乱码日产精品a级毛片久久| a级片免费观看视频| 亚洲特级aaaaaa毛片| 在线观看人成视频免费| 一区二区视频在线免费观看| 亚洲精品成人片在线观看精品字幕| 四虎成人精品永久免费AV| 中文字幕亚洲码在线| 亚洲毛片网址在线观看中文字幕| 国产拍拍拍无码视频免费| 亚洲av片不卡无码久久| 免费亚洲视频在线观看| 久久国产精品国产自线拍免费 | 免费看又黄又爽又猛的视频软件| 亚洲国产成人一区二区三区| 成人免费视频网站www| 日韩在线观看视频免费| 亚洲理论片在线观看| 国产成人精品日本亚洲专区 | 麻豆视频免费播放|