【问题标题】:React Native Align button on top of keyboard for all devices所有设备键盘顶部的 React Native Align 按钮
【发布时间】:2019-06-24 15:54:36
【问题描述】:

所以我需要对齐一个按钮Which is not at bottom om screen,按设计应该在屏幕中间,但它应该对齐在所有设备的键盘顶部。

如果您查看此屏幕截图:

对于某些设备我可以做到,但在其他一些设备上并没有真正对齐:

我该如何管理它以使其正常工作?

这是我到目前为止所做的:

<Padding paddingVertical={isKeyboardOpen ? Spacing.unit : Spacing.small}>
<Button
      variant="solid"
      label='Next'
      style={styles.submitBtn}
    />

</Padding>

isKeyboardOpen 只是一个基于平台创建监听器的方法,如果键盘打开则返回 true:

 Keyboard.addListener(
  Platform.OS === 'ios' ? 'keyboardWillShow' : 'keyboardDidShow',
  true 
 );

submitBrn css 类是:

submitBtn: {
  margin: Spacing.base,
},

【问题讨论】:

标签: typescript react-native


【解决方案1】:

首先导入这个包

import {
  Button,
  ScrollView,
  KeyboardAvoidingView,
  TextInput,
} from 'react-native';

渲染方法

 <KeyboardAvoidingView
  {...(Platform.OS === 'ios' ? { behavior: 'padding' } : {})}
  style={styles.container}>
  <ScrollView style={styles.scrollView}>
    <TextInput style={styles.input} placeholder="Tap here" />
  </ScrollView>
  <Button title="Next" />
</KeyboardAvoidingView>

这是样式

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  scrollView: {
    paddingHorizontal: 20,
  },
  input: {
    marginBottom: 20,
    borderBottomWidth: 2,
    borderColor: '#dbdbdb',
    padding: 10,
  },
});

确保按钮在滚动视图之外。

注意:如果键盘启用了自动完成功能,您可能需要调整 KeyboardAvoidingView 的 offset 属性。

Stick button at the bottom of the screen demo

【讨论】:

  • 不是真的,我已经通过KeyboardAvoidingView,但我的情况不同,不同平台(ios,android)和不同设备的键盘有不同的大小,我的按钮设计它必须位于中间文本框聚焦之前的屏幕,当聚焦时,它应该卡在所有平台和设备的键盘顶部。在您的示例中,按钮位于屏幕底部,无需调整按钮。
  • 当键盘出现并滚动输入时发生
  • 这只能在 Android 上对其他人有效吗?
  • 不,它适用于 android 和 ios。我会再次检查最新版本。
  • @GrantSingleton 感谢您发现该错误,在最新版本中,我们不需要 android 的行为道具。
【解决方案2】:

如果有人仍在寻找解决方案,我将发布 2021 年 10 月的工作示例以及 react 本机文档。此示例适用于文本输入,当获得焦点时,键盘上方有一个标记为“扫描仪”的按钮。 React 本机文档将我们在此处创建的内容称为“工具栏”。

更多详情请查看https://reactnative.dev/docs/next/inputaccessoryview

import {
  Button,
  ScrollView,
  TextInput,
  StyleSheet,
  InputAccessoryView,
  Text,
  View,
} from "react-native";
import { MaterialCommunityIcons } from "@expo/vector-icons";
import { BarCodeScanner } from "expo-barcode-scanner";
import { useFocusEffect } from "@react-navigation/native";

function CreateSearchBar() {
  const inputAccessoryViewID = "uniqueID";
  const [hasPermission, setHasPermission] = useState(null);
  const [scanned, setScanned] = useState(false);
  const [showScanner, setShowScanner] = useState(false);

  useEffect(() => {
    (async () => {
      const { status } = await BarCodeScanner.requestPermissionsAsync();
      setHasPermission(status === "granted");
    })();
  }, []);

  useFocusEffect(
    React.useCallback(() => {
      // Do something when the screen is focused
      return () => {
        // Do something when the screen is unfocused
        // Useful for cleanup functions
        setShowScanner(false);
      };
    }, [])
  );

  onChangeSearch = (search) => {};

  setScannerShow = (show) => {
    setShowScanner(show);
  };

  const handleBarCodeScanned = ({ type, data }) => {
    setScanned(true);
    setShowScanner(false);
    alert(`Bar code with type ${type} and data ${data} has been scanned!`);
  };

  if (hasPermission === null) {
    return <Text>Requesting for camera permission</Text>;
  }
  if (hasPermission === false) {
    return <Text>No access to camera</Text>;
  }

  if (showScanner) {
    return (
      <View style={styles.scanner}>
        <BarCodeScanner
          onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
          style={StyleSheet.absoluteFillObject}
        />
        {scanned && (
          <Button
            title={"Tap to Scan Again"}
            onPress={() => setScanned(false)}
          />
        )}
      </View>
    );
  }

  return (
    <>
      <ScrollView keyboardDismissMode="interactive">
        <View style={styles.input}>
          <MaterialCommunityIcons name="magnify" size={24} color="black" />
          <TextInput
            onChangeText={onChangeSearch}
            inputAccessoryViewID={inputAccessoryViewID}
            placeholder="Find items or offers"
          />
          <MaterialCommunityIcons
            name="barcode"
            size={30}
            color="black"
            onPress={() => setScannerShow(true)}
          />
        </View>
      </ScrollView>
      <InputAccessoryView nativeID={inputAccessoryViewID}>
        <Button onPress={() => setScannerShow(true)} title="Scanner" />
      </InputAccessoryView>
    </>
  );
}
const styles = StyleSheet.create({
  input: {
    height: 40,
    margin: 12,
    borderWidth: 1,
    padding: 10,
    flexDirection: "row",
    justifyContent: "space-between",
  },
  scanner: {
    height: "50%",
  },
});

export default CreateSearchBar;

【讨论】:

    【解决方案3】:

    你可以使用 react native modal

     <KeyboardAvoidingView
        keyboardVerticalOffset={Platform.OS == "ios" ? 10 : 0}
        behavior={Platform.OS == "ios" ? "padding" : "height"} style={{ flex: 1         }} >
        <Modal>
    
           <ScrollView>  
          <Content><-------Your content------></Content>
           </ScrollView>  
    
          <BottomButton   />
        </Modal>
      </KeyboardAvoidingView>
    

    【讨论】:

      猜你喜欢
      • 2023-03-10
      • 2017-07-30
      • 1970-01-01
      • 2018-03-16
      • 2017-12-15
      • 2014-03-05
      • 1970-01-01
      相关资源
      最近更新 更多