Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Native Align button on top of keyboard for all devices

So I need to align a button Which is not at bottom om screen by design should be at middle of screen but it should align to be on top of the keyboard for all devices.

If you check this screenshot :

enter image description here

for Some devices I mange to do it, but in some others is not really aligned :

enter image description here

how can I manage this to work in all?

this is what I did so far :

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

</Padding>

And isKeyboardOpen is just a method which will create a listner based on the platform return true if keyboard is open :

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

And submitBrn css class is :

submitBtn: {
  margin: Spacing.base,
},
like image 979
Emad Dehnavi Avatar asked Jan 31 '19 08:01

Emad Dehnavi


People also ask

How do you position a button in React Native?

Position button at the bottom The solution is to use add a container for the button, and use flex-end inside so that the button moves to the bottom. The flex tells the bottom view to take the remaining space. And inside this space, the bottom is laid out from the bottom, that's what the flex-end means.

What is keyboardVerticalOffset?

keyboardVerticalOffset ​ This is the distance between the top of the user screen and the react native view, may be non-zero in some use cases. Type. Default. number. 0.

How do you make your React Native app respond gracefully when the keyboard pops up?

The most simple solution, and the easiest to install, is KeyboardAvoidingView. It's a core component but it's also pretty simple in what it does. You can take the base code, which has the keyboard covering the inputs, and update that so that the inputs are no longer covered.


1 Answers

In case anyone is still looking for a solution to this I am posting a working example from October 2021 along with the react native documentation. This example is for a text input that when focused has a button labeled 'Scanner' above the keyboard. React native documentation refers to what we are creating here as a 'toolbar'.

Please see this for further details 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;
like image 114
Awesome Dev Avatar answered Oct 03 '22 03:10

Awesome Dev