RN系统组件三

1. FlatList:一个高性能的列表组件

基础使用:data、renderItem、keyExtractor
ScrollView属性:内容容器、滚动条、滚动监听、键盘模式等
横向纵向:horizontal
表头:ListHeaderComponent
表尾:ListFooterComponent
空元素:ListEmptyComponent
分隔线元素:ItemSeparatorComponent
初始渲染元素:initialNumToRender
反向:inverted
多列排布:numColumns
可见元素回调:onViewableItemsChanged
滚动到指定元素:scrollToIndex()、scrollToItem() 不推荐
滚动指定距离:scrollToOffset()
滚动到底:scrollToEnd()

FlatListDemo.js

import { useEffect, useRef } from "react";
import { Text, View, StyleSheet, FlatList } from "react-native";

const data = [
    1, 2,  3, 4, 5, 6, 7, 8, 9, 10,
    11, 12,  13, 14, 15, 16, 17, 18, 19, 20,
]

export default () => {
    const flastRef = useRef(null);
    useEffect(() => {
        setTimeout(() => {
            flastRef.current.scrollToIndex({
                index: 15,
                viewPosition: 1, //0表示顶部,1表示底部
                animated: true
            });
        }, 2000)
    })
    
    const renderItem = ({item, index}) => {
        return (
            <Text style={styles.txt}>{`List item ${item}`}</Text>
        );
    };

    const ListHeader = (
        <View>
            <Text style={styles.txt}>Flast List header</Text>
        </View>
    );

    const ListFooter = (
        <View>
            <Text style={styles.txt}>Flast List Footer</Text>
        </View>
    );

    const ListEmpty = (
        <Text style={styles.listEmpty}>暂无数据哦~</Text>
    );

    const ItemSeparator = (
        <View style={styles.divider}></View>
    );

    return(
        <FlatList
            ref={flastRef}
            style={styles.root}
            data={data}
            // data={[]}
            renderItem={renderItem}
            keyExtractor={(item, index) => `item-${index}` }
            ListHeaderComponent={ListHeader}
            ListFooterComponent={ListFooter}
            ListEmptyComponent={ListEmpty}
            ItemSeparatorComponent={ItemSeparator}
            initialNumToRender={15}
            // inverted={true}
            // numColumns={2}
            onViewableItemsChanged={(info) => {
                const {viewableItems} = info;
                console.log(viewableItems);
            }}
        >

        </FlatList>
    );
}

const styles = StyleSheet.create({
    root: {
        width: '100%',
        height: '100%',
        backgroundColor: '#f0f0f0',
    },
    txt: {
        fontSize: 20,
        fontWeight: 'bold',
        margin: 20
    },
    listEmpty: {
        width: '100%',
        height: 500,
        fontSize: 20,
        fontWeight: 'bold',
        textAlign: 'center',
        textAlignVertical: 'center'
    },
    divider: {
        width: '100%',
        height: 0.5,
        backgroundColor: '#dedede',
    },
});

2. SectionList:强中之强,多类型分组列表

基础使用:sections、renderItem、keyExtractor
ScrollView属性:内容容器、滚动条、滚动监听、键盘模式等
表头:ListHeaderComponent
表尾:ListFooterComponent
分组头部:renderSectionHeader
分割线元素:ItemSeparatorComponent
分组吸顶:stickySectionHeadersEnabled
滚动api:scrollToLocation()

import { View, StyleSheet, SectionList, Text } from "react-native"
import { SectionData } from "../constants/Data";
import { useEffect, useRef } from "react";

export default () => {
    const renderItem = ({item, index, section}) => {
        return (
            <Text style={styles.txt}>{item}</Text>
        );
    };

    const renderSectionHeader = ({section}) => {
        return (
            <Text style={styles.sectionHeader}>{section.type}</Text>
        );
    };

    const sectionListRef = useRef(null);
    useEffect(() => {
        setTimeout(() => {
            sectionListRef.current.scrollToLocation({
                sectionIndex: 1,
                itemIndex: 2,
                // viewPosition: 0,
                
            });
        }, 2000);
    }, []);
    
    return (
        <SectionList
            ref={sectionListRef}
            style={styles.root}
            sections={SectionData}
            renderItem={renderItem}
            keyExtractor={(item, index) => `item-${index}`}
            renderSectionHeader={renderSectionHeader}
            stickySectionHeadersEnabled={true}
        >

        </SectionList>
    );
}

const styles = StyleSheet.create({
    root: {
        width: '100%',
        height: '100%',
        backgroundColor: '#f0f0f0',
    },
    txt: {
        fontSize: 20,
        height: 56,
        width: '100%',
        color: "#333",
        textAlignVertical: 'center',
        textAlign: 'center'
    },
    sectionHeader: {
        width: '100%',
        height: 36,
        backgroundColor: 'red',
        textAlign: 'center',
        fontSize: 22,
    }
});

3. RefreshControl:下拉刷新,上拉加载,用我没错

下拉刷新:refreshing、onRefresh
上拉加载:onEndReached、onEndReachedThreshold

import { View, StyleSheet, SectionList, Text, RefreshControl } from "react-native"
import { SectionData } from "../constants/Data";
import { useEffect, useRef, useState } from "react";

export default () => {
    const renderItem = ({item, index, section}) => {
        return (
            <Text style={styles.txt}>{item}</Text>
        );
    };

    const renderSectionHeader = ({section}) => {
        return (
            <Text style={styles.sectionHeader}>{section.type}</Text>
        );
    };

    const sectionListRef = useRef(null);
    const [refreshing, setRefreshing] = useState(false)

    // useEffect(() => {
    //     setTimeout(() => {
    //         sectionListRef.current.scrollToLocation({
    //             sectionIndex: 1,
    //             itemIndex: 2,
    //             // viewPosition: 0,
                
    //         });
    //     }, 2000);
    // }, []);
    
    return (
        <SectionList
            ref={sectionListRef}
            style={styles.root}
            sections={SectionData}
            renderItem={renderItem}
            keyExtractor={(item, index) => `item-${index}`}
            renderSectionHeader={renderSectionHeader}
            stickySectionHeadersEnabled={true}
            refreshControl={
                <RefreshControl
                    refreshing={refreshing}
                    onRefresh={() => {
                        console.log("onRefresh...");
                        setRefreshing(true);
                        //request new data
                        setTimeout(() => {
                            setRefreshing(false);
                        }, 2000)
                    }}
                    
                >
                </RefreshControl>
            }
            onEndReached={() => {
                console.log('onEndReached...')
            }}
            onEndReachedThreshold={0.3}
        >

        </SectionList>
    );
}

const styles = StyleSheet.create({
    root: {
        width: '100%',
        height: '100%',
        backgroundColor: '#f0f0f0',
    },
    txt: {
        fontSize: 20,
        height: 56,
        width: '100%',
        color: "#333",
        textAlignVertical: 'center',
        textAlign: 'center'
    },
    sectionHeader: {
        width: '100%',
        height: 36,
        backgroundColor: 'red',
        textAlign: 'center',
        fontSize: 22,
    }
});

4. Modal:实现不同样式的弹窗

控制显示:visible
渲染内容:children
安卓返回关闭:onRequestClose
背景透明:transparent
状态栏透明:statusBarTranslucent
动画方式:animationType
状态回调:onShow、onDismiss
背景动画:伏笔

ModalDemo.js

import { View, StyleSheet, Modal, Text, SectionList, Button, Image, TouchableOpacity } from "react-native"
import { SectionData } from "../constants/Data";
import { useRef, useState } from "react";
import close from "../assets/images/icon_close_modal.png"

export default () => {
    const [visible, setVisible] = useState(false);

    const showModal = () => {
        setVisible(true);
    }

    const hideModal = () => {
        setVisible(false);
    }



    const renderItem = ({ item, index, section }) => {
        return (
            <Text style={styles.txt}>{item}</Text>
        );
    };

    const renderSectionHeader = ({ section }) => {
        return (
            <View style={styles.sectionHeader}>
                <Text style={styles.sectionHeader}>{section.type}</Text>
            </View>


        );
    };

    const listHeader = () => {
        return (
            <View style={styles.listHeader}>
                <Text style={styles.listHeader}>
                    列表头部
                </Text>
                <TouchableOpacity
                    style={styles.iconButton}
                    onPress={() => {
                        hideModal()
                    }}
                >
                    <Image
                        source={close}
                        style={styles.icon}
                    />
                </TouchableOpacity>
            </View>

        );
    }

    return (
        <View style={styles.root}>
            <Button title="按钮" onPress={() => {
                showModal();
            }} />
            <Modal
                visible={visible}
                onRequestClose={() => {
                    hideModal();
                }}
                transparent={true}
                // statusBarTranslucent={true}
                animationType="slide"
                onShow={() => {
                    console.log('onShow...')
                }}
                onDismiss={() => {
                    //有问题,不回调
                    console.log('onDismiss...')
                }}
            >
                <View style={styles.blank}></View>
                <View style={styles.content}>
                    <SectionList
                        style={styles.sectionList}
                        sections={SectionData}
                        renderItem={renderItem}
                        keyExtractor={(item, index) => `item-${index}`}
                        renderSectionHeader={renderSectionHeader}
                        stickySectionHeadersEnabled={true}
                        ListHeaderComponent={listHeader}
                    >

                    </SectionList>
                </View>
            </Modal>
        </View>
    );
}

const styles = StyleSheet.create({
    root: {
        width: '100%',
        height: '100%',
        padding: 20,
    },
    content: {
        width: '100%',
        height: '90%',
        backgroundColor: "#ff000030"
    },
    sectionList: {
        width: '100%',
        height: '100%',
        backgroundColor: '#f0f0f0',
    },
    txt: {
        fontSize: 20,
        height: 56,
        width: '100%',
        color: "#333",
        textAlignVertical: 'center',
        textAlign: 'center'
    },
    sectionHeader: {
        width: '100%',
        height: 36,
        backgroundColor: 'red',
        textAlign: 'center',
        fontSize: 22,
        justifyContent: 'center'
    },
    blank: {
        width: '100%',
        height: '10%',
        backgroundColor: '#00000050'
    },
    icon: {
        width: 24,
        height: 24,
    },
    iconButton: {
        // width: 24,
        // height: 24,
        position: 'absolute',
        right: 16
    },
    listHeader: {
        width: '100%',
        height: 36,
        backgroundColor: 'yellow',
        textAlign: 'center',
        fontSize: 22,
        justifyContent: 'center',
        textAlignVertical: 'center'
    },
})

5. StatusBar:状态栏适配的难题交我

内容深浅模式:barStyle
背景颜色:backgroundColor
动画切换:animated
透明悬浮:translucent
隐藏状态栏:hidden
api:setBackgroundColor()、setBarStyle()、setHidden()、setTranslucent()

<StatusBar 
                barStyle={"dark-content"}
                backgroundColor='white'
                // animated={true}
                // translucent={true}
                hidden={false}
            />

6. Switch:开关切换,一键搞定

指定开关:value
状态回调:onValueChange
设置不可用:disabled
背景颜色:trackColor
前景颜色:thumbColor

import { useState } from "react";
import { View, StyleSheet, Switch } from "react-native"


export default()=> {
    const [switchValue, setSwitchValue] = useState(false);

    return (
        <View style={styles.root}>
            <Switch 
                value={switchValue}
                onValueChange={(value) => {
                    console.log(`value: ${value}`)
                    setSwitchValue(value);
                }}
                // disabled={true}
                trackColor={{true: 'red', false: 'yellow'}}
                thumbColor='#0f0'
            />
        </View>
    );
}

const styles = StyleSheet.create({
    root: {
        width: '100%',
        height: '100%',
        backgroundColor: '#f0f0f0'
    }
})
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容