0

我需要帮助。我在 React Native 中制作了一个聊天应用程序,但是当我向上滚动浏览一些聊天时遇到了一些问题,然后当我点击 TextInput 时,我的 FlatList 或 VirtualizedList 从索引 0 开始,这是我不想要的,我所期望的就像在WhatsApp中一样,在滚动了一些距离之后,当我们按下输入字段时它不会滚动到底部而是静止不动

分享这方面的视频。 https://youtu.be/DvrdTFWpREo

我使用 REST 国家 API https://restcountries.eu/重现了这里的场景

我没有改变任何状态,因此我认为它不是重新渲染。

要点链接:https ://gist.github.com/sultanularefin/7eb11e5d278020bffd1d51ac58efd664

import React, {
    useState,
    useRef,
    useEffect,
} from 'react';


import {
    Dimensions,
    Text,
    View,
    FlatList,
    TouchableOpacity,
    TextInput,
    StyleSheet,
    Keyboard,
    VirtualizedList,
    ListRenderItem,
} from 'react-native';


import Icon from 'react-native-vector-icons/Ionicons';
import MTI from 'react-native-vector-icons/MaterialCommunityIcons';

export interface Props {

}


export interface Currency {
    code: string;
    name: string;
    symbol: string;
}

export interface Language {
    iso639_1: string;
    iso639_2: string;
    name: string;
    nativeName: string;
}

export interface Translations {
    de: string;
    es: string;
    fr: string;
    ja: string;
    it: string;
    br: string;
    pt: string;
    nl: string;
    hr: string;
    fa: string;
}

export interface RegionalBloc {
    acronym: string;
    name: string;
    otherAcronyms: string[];
    otherNames: string[];
}

export interface RootObject {
    name: string;
    topLevelDomain: string[];
    alpha2Code: string;
    alpha3Code: string;
    callingCodes: string[];
    capital: string;
    altSpellings: string[];
    region: string;
    subregion: string;
    population: number;
    latlng: number[];
    demonym: string;
    area?: number;
    gini?: number;
    timezones: string[];
    borders: string[];
    nativeName: string;
    numericCode: string;
    currencies: Currency[];
    languages: Language[];
    translations: Translations;
    flag: string;
    regionalBlocs: RegionalBloc[];
    cioc: string;
    key: string;
}

const genericHeight =  50;

const itemLayoutHeights: Array<number> = [];


const App2: React.FC<Props> = ({}) => {


    const deviceWidth = Dimensions.get('window').width;
    const deviceHeight = Dimensions.get('window').height;
    const [error, setError] = useState(null);
    const [isLoaded, setIsLoaded] = useState(false);
    const [allCountryInfo, setAllCountryInfo] = useState<Array<RootObject>>();
    const [messageInputState, setMessageInputState] = useState('');

    const partnerChatsVLLRef = useRef<FlatList>(null);
    const messageInputRef = useRef(null);


    const onChangeTextLoggerInput = (inputValue:string) => {
        console.log(` inputValue ==> ${inputValue}`);
        setMessageInputState(inputValue);
    };



    useEffect(() => {



        const getData = ()=> {
            const url = 'https://restcountries.eu/rest/v2/';


            fetch(url)
                .then(res => res.json())
                .then(
                    (result) => {
                        setError(null);
                        setIsLoaded(true);


                        const allResult = result.map((oneInterest: RootObject) => ({
                                    ...oneInterest,
                                    key: oneInterest.nativeName,
                                }
                            )
                        );

                        setAllCountryInfo(allResult);


                    },

                    (error3) => {
                        setIsLoaded(true);
                        setError(error3);
                        setAllCountryInfo([]);

                    }
                ).catch((error2) => {
                console.log('error2: ', error2);
                setIsLoaded(true);

                setAllCountryInfo([]);


            });

        };


        getData();

    }, []);



    const renderItemGetItemLayOut: ListRenderItem<RootObject> = ({
                                                                     item,
                                                                     index,
                                                                     separators }) =>  {


        return (
            <View
                style={{
                    height: genericHeight,
                    width: deviceWidth,
                    backgroundColor: '#f9c2ff',
                    borderWidth: 1,
                    paddingStart: 10,

                }}


                onLayout={ (object) =>{
                    itemLayoutHeights[index] = object.nativeEvent.layout.height;
                }}


            >
                <Text
                    style={{

                        fontSize: 32,
                        color: 'black',
                        width: deviceWidth,
                        textAlign: 'left',

                    }}>
                    {index}:  {item.name}
                </Text>
            </View>
        );
    };


    // NHS F.... NHS Fianl..

    console.log("allCountryInfo.length: ", allCountryInfo?.length);

    return (
        <View style={{
            flex: 10,
            flexDirection: 'column',
        }}>
            <View style={{
                flex: 9,
                paddingVertical: 8,
                justifyContent: "flex-start",
            }}
            >

                <FlatList
                    style={{
                    }}
                    ref= {partnerChatsVLLRef}
                    data= {allCountryInfo}
                    renderItem= {renderItemGetItemLayOut}
                    keyExtractor= {(item) => item.key}
                    inverted={true}
                    getItemLayout = {(data, index) => ({
                            length: (itemLayoutHeights[index] === undefined)
                                ? 100
                                : itemLayoutHeights[index],
                            offset: itemLayoutHeights.slice(0, index).reduce((a, c) => a + c, 0),
                            index,
                        }
                    )}

                />
            </View>

            <View style={{
                flexDirection: 'column',
                flex: 1,
                paddingBottom: 20,
                width: deviceWidth,


            }}
            >
                <View style={partnerChatsStyle.messageinputcontainerElse}>
                    <TextInput
                        style={partnerChatsStyle.messageinputElse}
                        placeholder="Enter Message"
                        ref={messageInputRef}
                        onChangeText={
                            (text) => onChangeTextLoggerInput(text)

                        }

                        onPressIn={
                            (e) => {
                                console.log("event for onPressIn: ", e.target.viewConfig.uiViewClassName);
                                // e.preventDefault();
                            }

                        }


                        onFocus={
                            (e) =>{

                                console.log("event for onFocus", e.target.viewConfig.uiViewClassName);
                                // e.preventDefault();
                            }
                        }

                    />

                    <View style={{
                        flex: 0.15,
                        flexDirection: 'row',
                        justifyContent: 'flex-start',
                        paddingLeft: 7,

                    }}
                    >
                        <TouchableOpacity

                            onPress={() => console.log("invokeActionSheet()")}
                        >
                            <Icon
                                size={40}
                                color='black'
                                name={'ios-attach'}

                            />
                        </TouchableOpacity>
                    </View>


                    <View style={{
                        flex: 0.15,
                        flexDirection: 'row',
                        justifyContent: 'flex-start',
                        paddingLeft: 7,

                    }}
                    >
                        <TouchableOpacity
                            style={partnerChatsStyle.roundedbackgroudElse}
                            onPress= { () =>console.log("insertChatAndImagesToServer")}
                        >
                            <MTI
                                size={45}
                                style={{
                                    color: 'white',
                                    textAlign: 'left',
                                    alignSelf: 'stretch',
                                    fontSize: 40
                                }}
                                name={'send-circle'}
                            />
                        </TouchableOpacity>
                    </View>
                </View>
            </View>
        </View>

    );

};

const partnerChatsStyle = StyleSheet.create({
    messageinputElse: {
        flex: 0.7,
        textAlign: 'justify',
        height: 50,
        borderWidth: 1,
        borderColor: '#e0e0e0',
        borderRadius: 20,
        backgroundColor: '#FFFFFF',
        paddingLeft: 10,
        color: 'black',
    },

    messageinputcontainerElse: {
        flex: 1,
        flexDirection: 'row',
        height: 50,
        backgroundColor: 'transparent',
        marginLeft: 10,
    },

    roundedbackgroudElse: {
        height: 40,
        width: 40,
        justifyContent: 'center',
        borderRadius: 70,
        backgroundColor: 'black',
    },

});

export default App2;

4

0 回答 0