gpt4 book ai didi

android - react 原生 : Android soft keyboard push the View up

转载 作者:行者123 更新时间:2023-12-04 23:45:11 27 4
gpt4 key购买 nike

我制作了一张自定义动画底页。它有两个捕捉点。它从屏幕顶部开始,如果向下滚动动画卡片,它将来到屏幕中间,再次向下滚动卡片,它将来到屏幕底部。如果用户用力向下滚动动画卡片,那么它将一直向下滚动。我将此组件制作为可重复使用的组件。
我已经制作了可重复使用的 搜索组件 .
我将这两个组件都导入了 主应用 零件。里面动画底页我把 搜索组件 .
我已经为 设置了条件键盘 动画。查看

  • 如果动画 View 从屏幕中间移动到底部并搜索 聚焦 (键盘出现)然后键盘 将解雇。
  • 如果动画 View 位于屏幕底部并搜索输入 onfocus (键盘出现)然后它将移动屏幕中间的动画 View 。对于这个逻辑,我做了Keyboard.addListener('keyboardDidHide',()=>{....})

  • 我的这个逻辑在 IOS 中完美运行,但在 Android 中,它将所有元素推到屏幕顶部。
    有很多关于 KeyboardAvoidingView 的建议,但就我而言,它不起作用。
    在 react-native 的 android 的 AndroidManifest.xml 文件中。我做了 android:windowSoftInputMode="adjustPan"它听 Keyboard.addListener('keyboardDidHide'并将所有元素推到屏幕顶部,如果我制作 android:windowSoftInputMode="adjustPan|adjustResize"那么它不听 Event-lister .结果,我的逻辑不起作用,它隐藏了 Android 键盘下的动画 View 。根据 RN-documentation , 事件列表器只听 adjustResize or adjustPan .
    问题:
    我真的不知道如何解决这个问题
    Android 设备行为
    DEMO
    代码演示
    expo-snacks
    这是我的动画 View 组件
    import React, { useState } from "react";
    import { StyleSheet, Dimensions, Platform, View, Keyboard } from "react-native";
    import {
    PanGestureHandler,
    PanGestureHandlerGestureEvent,
    } from "react-native-gesture-handler";

    import Animated, {
    useAnimatedGestureHandler,
    useAnimatedStyle,
    useSharedValue,
    withTiming,
    withSpring,
    runOnJS,
    Easing,
    } from "react-native-reanimated";
    import styled from "styled-components/native";

    interface Props {
    children: React.ReactNode;
    }

    const { height: SCREEN_HEIGHT } = Dimensions.get("screen");

    const IPHONE_DEVICE_MIDDLE_SCREEN = Platform.OS === "ios" ? 4 : 4;
    const IPHONE_DEVICE_BOTTOM_SCREEN = Platform.OS === "ios" ? 7.6 : 7.36;
    const ANIMATED_DURATION = 300;

    const LoadingContainer = styled.View`
    height: ${SCREEN_HEIGHT - 300}px;
    background-color: #fff;
    justify-content: center;
    `;

    const ScrollBottomSheet = ({ children }: Props) => {
    const contentTop = useSharedValue(SCREEN_HEIGHT);
    const [bottomSheetState, setBottomSheetState] = useState("top");
    // Event-listener
    Keyboard.addListener("keyboardDidShow", () => {
    if (bottomSheetState === "bottom") {
    contentTop.value = withSpring(
    SCREEN_HEIGHT * IPHONE_DEVICE_MIDDLE_SCREEN
    );
    }
    });
    const animatedStyle = useAnimatedStyle(() => {
    "worklet";
    return {
    top: contentTop.value * 0.1,
    bottom: 0,
    };
    });

    const gestureHandler = useAnimatedGestureHandler(
    {
    onStart(_, context) {
    context.translateY = contentTop.value;
    },
    onActive(event, context) {
    contentTop.value = context.translateY + event.translationY;
    },
    onEnd(event, _) {
    if (event.y > 0 && event.y < 200) {
    // MIDDLE SCREEN LOGIC
    contentTop.value = withTiming(
    SCREEN_HEIGHT * IPHONE_DEVICE_MIDDLE_SCREEN,
    {
    duration: ANIMATED_DURATION,
    easing: Easing.inOut(Easing.ease),
    }
    );
    runOnJS(setBottomSheetState)("middle");
    runOnJS(Keyboard.dismiss)(); // dismiss Keyboard
    } else if (event.y > 200) {
    // BOTTOM SCREEN LOGIC
    contentTop.value = withTiming(
    SCREEN_HEIGHT * IPHONE_DEVICE_BOTTOM_SCREEN,
    {
    duration: ANIMATED_DURATION,
    easing: Easing.inOut(Easing.ease),
    }
    );
    runOnJS(Keyboard.dismiss)();
    runOnJS(setBottomSheetState)("bottom");
    } else if (event.translationY < 0) {
    contentTop.value = withTiming(SCREEN_HEIGHT, {
    duration: ANIMATED_DURATION,
    easing: Easing.inOut(Easing.ease),
    });
    runOnJS(setBottomSheetState)("top");
    }
    },
    },
    [contentTop]
    );

    return (
    <PanGestureHandler onGestureEvent={gestureHandler}>
    <Animated.View style={[styles.container, animatedStyle]}>
    <View style={styles.grbber} />
    {children}
    </Animated.View>
    </PanGestureHandler>
    );
    };

    export default ScrollBottomSheet;

    const styles = StyleSheet.create({
    container: {
    position: "absolute",
    left: 0,
    right: 0,
    top: 0,
    backgroundColor: "#fff",
    shadowOffset: {
    height: -6,
    width: 0,
    },
    shadowOpacity: 0.1,
    shadowRadius: 5,
    borderTopEndRadius: 15,
    borderTopLeftRadius: 15,
    },
    grbber: {
    width: 80,
    height: 5,
    marginBottom: 4,
    alignSelf: "center",
    marginTop: 5,
    borderTopWidth: 5,
    borderTopColor: "#aaa",
    },
    });
    搜索组件
    import React, { useRef, useEffect } from "react";
    import {
    Animated,
    KeyboardTypeOptions,
    TextInputProps,
    TextInput,
    Text,
    Keyboard,
    } from "react-native";

    import styled from "styled-components/native";

    type Props = TextInputProps & {
    text: string,
    hint: string,
    onChangeText?: ((text: string) => void) | undefined,
    onClearText: () => void,
    animatedStyle?: { height: Animated.AnimatedInterpolation },
    keyboardType?: KeyboardTypeOptions,

    autoFocus?: boolean,
    };

    const Container = styled(Animated.View)`
    flex-direction: row;
    background-color: grey;
    border-radius: 6px;
    align-items: center;
    `;

    const IconTouchableOpacity = styled.TouchableOpacity`
    padding: 16px;
    `;

    const SearchInput = styled.TextInput`
    flex: 1;
    padding-right: 16px;
    color: #fff;
    font-size: 16px;
    line-height: 20px;
    height: 44px;
    `;

    const SearchBar = ({
    text,
    hint,
    onChangeText,
    onClearText,
    animatedStyle,
    keyboardType,
    maxLength,
    autoFocus,
    }: Props) => {
    const searchInput = useRef(null);

    const onSearchPress = () => {
    searchInput?.current?.focus();
    };

    useEffect(() => {
    if (autoFocus) {
    onSearchPress();
    }
    }, [autoFocus]);

    return (
    <Container accessible={false} style={animatedStyle}>
    <SearchInput
    ref={searchInput}
    onChangeText={onChangeText}
    value={text}
    placeholder={hint}
    maxLength={maxLength}
    underlineColorAndroid={"transparent"}
    placeholderTextColor={"grey"}
    keyboardType={keyboardType}
    autoFocus={autoFocus}
    onKeyPress={() => hideKeyBoard}
    />
    </Container>
    );
    };

    export default SearchBar;
    **应用组件
    import React, { useState, useEffect } from "react";
    import { StyleSheet, Button } from "react-native";
    import { TouchableHighlight } from "react-native-gesture-handler";
    import MapView from "react-native-maps";
    import styled from "styled-components";
    import ScrollBottomSheet from "./components/ActionSheet";
    import SearchBar from "./components/SearchBar";

    const initialRegion = {
    latitudeDelta: 15,
    longitudeDelta: 15,
    latitude: 60.1098678,
    longitude: 24.7385084,
    };

    export default function App() {
    return (
    <>
    <MapView style={styles.mapStyle} initialRegion={initialRegion} />
    <ScrollBottomSheet>
    <SearchContainer>
    <SearchBar hint={"search"} />
    </SearchContainer>
    </ScrollBottomSheet>
    </>
    );
    }

    const styles = StyleSheet.create({
    mapStyle: {
    height: "100%",
    },
    });

    const SearchContainer = styled.View`
    padding: 10px;
    `;

    最佳答案

    您是否尝试过使用 Animated.ScrollView 而不是 Animated.View?

    关于android - react 原生 : Android soft keyboard push the View up,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69496553/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com