简体   繁体   English

React-Native:Modal中的Flatlist无法滚动

[英]React-Native: Flatlist in Modal unable to scroll

I'm having an issue with scrolling in lists that are in modals ever since upgrading to the latest React-Native version (0.55.4).自从升级到最新的 React-Native 版本 (0.55.4) 以来,我一直在滚动模式列表中的问题。 In this case it is a Flatlist在这种情况下,它是一个平面列表

The Flatlist with the problem is inside a modal, which is in another modal that is rendered as a footer component on another Flatlist (it is an add button).存在问题的 Flatlist 位于模态框内,该模态框位于另一个模态中,该模态呈现为另一个 Flatlist 上的页脚组件(它是一个添加按钮)。

Please help!请帮忙! Thank you谢谢

Code:代码:

Flatlist Footer Component (Add Button): Flatlist 页脚组件(添加按钮):

@observer
class AddButton extends Component {
    @observable visible = false;

    constructor(props) {
        super(props);
        this.state = {
            mergeName: '',
            coin: undefined
        };
    }
    show = () => {
        this.visible = true;
    };

    hide = () => {
        this.visible = false;
    };

    render() {

        return (
            <View>
                <Button
                    primary
                    onPress={() => {
                        this.show();
                    }}
                    title={'add'}
                    style={{
                        width: '50%',
                        alignSelf: 'center',
                        marginVertical: 16
                    }}
                />
                <Modal
                    visible={this.visible}
                    animationType='slide'
                    onRequestClose={this.hide}
                >
                    <Screen>
                        <View style={{ padding: 5, backgroundColor: '#0003' }}>
                            <TouchableOpacity
                                style={{
                                    width: '50%',
                                    height: 40,
                                    paddingHorizontal: 10,
                                    justifyContent: 'center'
                                }}
                                onPress={this.hide}
                            >
                                <Text style={{ color: '#fff' }}>
                                    {'cancel'}
                                </Text>
                            </TouchableOpacity>
                        </View>

                        <View>
                            <Row>
                                <RowLabel>{'coin'}:</RowLabel>
                                <Selector
                                    force
                                    ref={'mySelector'}
                                    value={this.coin}
                                    onSelect={coin => {
                                        this.handleSelect();
                                    }}
                                    data={allCoins}
                                />
                            </Row>
                            <Button
                                primary
                                onPress={this.handleSubmit}
                                title={this.props.i18n.'add'}
                                style={{
                                    width: '50%',
                                    alignSelf: 'center',
                                    marginVertical: 16
                                }}
                            />
                        </View>
                    </Screen>
                </Modal>
            </View>
        );
    }
}

export default AddButton;

const contentStyle = {
    flex: 1,
    backgroundColor: '#0003',
    paddingLeft: 10,
    borderRadius: 3
};

const Row = ({ style, ...rest }) => (
    <View
        style={[
            {
                height: 60,
                flexDirection: 'row',
                alignItems: 'center',
                padding: 10,
                marginRight: 10
            },
            style
        ]}
        {...rest}
    />
);

const RowLabel = props => (
    <Text style={{ width: 80, color: '#ccc' }} {...props} />
);

const Input = (props: TextInputProperties) => (
    <View style={contentStyle}>
        <TextInput
            placeholderTextColor='#fff3'
            style={{ color: '#ccc', flex: 1, fontSize: 14 }}
            {...props}
        />
    </View>
);

Problematic Flatlist in Modal Component (Selector):模态组件(选择器)中有问题的平面列表:

@observer
class Selector extends Component {
    @observable value = '';
    @observable visible = false;
    constructor(props) {
        super(props);
        if (props.modify) {
            this.selectValue();
        }
    }

    selectValue = () => {
        this.value = this.props.value;
    };

    show = () => {
        if (this.props.force) this.visible = true;
        if (!this.props.coin) return;
        this.visible = true;
    };

    hide = () => {
        this.filterText = '';
        this.visible = false;
    };

    handleSelect = item => {
        this.value = item;
        if (typeof this.props.onSelect === 'function') {
            this.props.onSelect(item);
        }
        this.hide();
    };

    componentWillReceiveProps(nextProps) {
        if (nextProps.value !== this.value) {
            this.value = nextProps.value || '';
        }
    }

    renderItem = ({ item }) => {
        return (
            <TouchableOpacity
                onPress={() => this.handleSelect(item)}
                style={{
                    backgroundColor: '#fff',
                    height: 40,
                    paddingLeft: 10,
                    justifyContent: 'center'
                }}
            >
                <Text style={{ fontSize: 14, color: '#333' }}>
                    {item.toUpperCase()}
                </Text>
            </TouchableOpacity>
        );
    };

    render() {
        let data = this.props.data;

        return (
            <View style={[ contentStyle, { justifyContent: 'center' } ]}>
                <TouchableOpacity
                    style={{
                        flex: 1,
                        flexDirection: 'row',
                        alignItems: 'center'
                    }}
                    onPress={this.show}
                >
                    <Text
                        numberOfLines={1}
                        style={{ color: this.value ? '#ccc' : '#fff3' }}
                    >
                        {(
                            this.value ||
                            this.props.placeholder ||
                            ''
                        ).toUpperCase()}
                    </Text>
                </TouchableOpacity>

                <Modal
                    transparent
                    animationType='fade'
                    visible={this.visible}
                    onRequestClose={this.hide}
                >
                    <View
                        style={{
                            flex: 1,
                            backgroundColor: '#0005',
                            alignItems: 'center',
                            paddingTop: 80
                        }}
                    >
                        <View
                            style={{
                                width: '80%',
                                backgroundColor: '#fff',
                                borderRadius: 5,
                                maxHeight: '80%',
                                overflow: 'hidden'
                            }}
                        >
                            <FlatList
                                data={data}
                                keyExtractor={i => i}
                                getItemLayout={(_, index) => {
                                    const height = 40 + HairSpacer.width;
                                    return {
                                        length: height,
                                        offset: height * index,
                                        index
                                    };
                                }}
                                ItemSeparatorComponent={HairSpacer}
                                renderItem={this.renderItem}
                            />
                        </View>
                        <TouchableOpacity
                            onPress={this.hide}
                            style={{ marginTop: 12 }}
                        >
                            <Icon
                                name='ios-close-circle'
                                size={50}
                                color='#ccc'
                            />
                        </TouchableOpacity>
                    </View>
                </Modal>
            </View>
        );
    }
}

export default Selector;

const contentStyle = {
    flex: 1,
    backgroundColor: '#0003',
    paddingLeft: 10,
    borderRadius: 3
};

I fixed this issue by Defining a fixed height for the flatlist container.我通过为 flatlist 容器定义固定高度来解决此问题。

For Eg例如

<View style={{height: 300}}>
   {hasResults ? (
       <FlatList
             data={searchResults}
             renderItem={renderItem}
             keyExtractor={(item): string => {
             return item.id;
            }}
             showsVerticalScrollIndicator={false}
         />
    ) : undefined}
</View>

According to official react native docs scrollview should have a bounded height to work.根据官方反应原生文档滚动视图应该有一个有界的高度才能工作。 I think same applies to flatlist.我认为这同样适用于平面列表。

https://reactnative.dev/docs/scrollview https://reactnative.dev/docs/scrollview

Keep in mind that ScrollViews must have a bounded height in order to work, since they contain unbounded-height children into a bounded container (via a scroll interaction). In order to bound the height of a ScrollView, either set the height of the view directly (discouraged) or make sure all parent views have bounded height. Forgetting to transfer {flex: 1} down the view stack can lead to errors here, which the element inspector makes quick to debug.

Make sure you have added the Flatlist in ScrollView and add keyboardShouldPersistTaps='always'确保您已在 ScrollView 中添加了 Flatlist 并添加了keyboardShouldPersistTaps='always'

<ScrollView style={{ flex: 1 }} keyboardShouldPersistTaps='always'>
            <FlatList
              .................
            />
 </ScrollView>

只需将keyboardShouldPersistTaps='always'添加到 FlatList

唯一对我Pressable的是将 FlatList 内部项目包装在FlatList内部

I solve with ScrollView, like this:我用 ScrollView 解决,像这样:

              <ScrollView>
                <FlatList
                  data={this.state.dataSource}
                  renderItem={({ item, index }) => (
                    <CountryItem item={item} index={index}/>
                  )}
                  horizontal={false}
                  onEndThreshold={0}
                  keyExtractor={item => ''.concat(Math.random())}/>
              </ScrollView>

or use ListView.或使用列表视图。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM