const headerHeight = useHeaderHeight();
const keyboardVerticalOffset = Platform.OS === 'ios' ? headerHeight + 20 : 0;
const behavior = Platform.OS === 'ios' ? 'padding' : 'height';
<SafeAreaView style={styles.wrapper}>
<KeyboardAwareScrollView
keyboardVerticalOffset={keyboardVerticalOffset}
behavior={behavior}
contentContainerStyle={{flexGrow: 1}}
style={{
backgroundColor: 'blue',
}}>
<View style={{flex: 1, backgroundColor: 'red', height: '100%'}}>
<Text>Details Screen</Text>
<View style={styles.priceInputWrapper}>
<Text style={styles.dollarSignText}>$</Text>
<TextInput
keyboardType="numeric"
style={styles.priceInput}
onChangeText={handlePriceValue}
value={priceValue}
placeholder="0"
/>
</View>
</View>
<ButtonTouchOpacity onPress={() => navigation.navigate('PostDelivery')}>
<Text>Save and Next</Text>
</ButtonTouchOpacity>
</KeyboardAwareScrollView>
</SafeAreaView>
I'm trying to set it so when the keyboard pops up, the button at the bottom will be above the keyboard. Trying to keep the button at the footer of the page.
IMO KeyboardAwareScrollView's use case is a bit different than yours. I use it when there is a situation that user can change focus between multiple inputs and they should be automatically aligned to a visible position. For cases like this, I use RN's KeyboardAvoidingView component. I don't know how strict you are on using KeyboardAwareScrollView, but if you are not that strict about it, here is a snippet that works with KeyboardAvoidingView:
import * as React from "react";
import {
View,
Button,
SafeAreaView,
Text,
TextInput,
Platform,
KeyboardAvoidingView
} from "react-native";
export default function App() {
const headerHeight = 20;
const keyboardVerticalOffset =
Platform.OS === "ios" ? headerHeight + 20 : 0;
const behavior = Platform.OS === "ios" ? "padding" : "height";
return (
<SafeAreaView style={{ flex: 1 }}>
<KeyboardAvoidingView
keyboardVerticalOffset={keyboardVerticalOffset}
behavior={behavior}
style={{
flex: 1
}}
>
<View
style={{ flex: 1, backgroundColor: "red", height: "100%" }}
>
<Text>Details Screen</Text>
<TextInput
style={{
width: 500,
height: 60,
backgroundColor: "cyan"
}}
/>
</View>
<Button
title="Save and Exit"
/>
</KeyboardAvoidingView>
</SafeAreaView>
);
}
You need to move the button outside the scrollview.
const headerHeight = useHeaderHeight();
const keyboardVerticalOffset = Platform.OS === 'ios' ? headerHeight + 20 : 0;
const behavior = Platform.OS === 'ios' ? 'padding' : 'height';
<SafeAreaView style={styles.wrapper}>
<KeyboardAwareScrollView
keyboardVerticalOffset={keyboardVerticalOffset}
behavior={behavior}
contentContainerStyle={{flexGrow: 1}}
style={{
backgroundColor: 'blue',
}}>
<View style={{flex: 1, backgroundColor: 'red', height: '100%'}}>
<Text>Details Screen</Text>
<View style={styles.priceInputWrapper}>
<Text style={styles.dollarSignText}>$</Text>
<TextInput
keyboardType="numeric"
style={styles.priceInput}
onChangeText={handlePriceValue}
value={priceValue}
placeholder="0"
/>
</View>
</View>
</KeyboardAwareScrollView>
<ButtonTouchOpacity onPress={() => navigation.navigate('PostDelivery')}>
<Text>Save and Next</Text>
</ButtonTouchOpacity>
</SafeAreaView>
Related
I'm learning react-native, currently learning state.
I have a TextInput on my screen:
however, when I try to type in it the text doesn't appear.
My code:
const Login = ({ navigation } : any) => {
const [text, setText] = useState('');
return (
<View style={[styles.container, { flexDirection: "column" }]}>
<View style={{ flex: 1, alignItems:"center", justifyContent:"center" }}>
<Image source={require('../assets/images/help.png') } style={{ width: 40, height: 40 }} />
</View>
<View style={{ flex: 2, backgroundColor: "#5f6364", borderTopRightRadius:20, borderTopLeftRadius:20 }}>
<TextInput style={styles.input} placeholder="Type here to translate!" onChangeText={newText => setText(newText)} defaultValue={text} />
</View>
</View>
)
}
Can someone explain why this is happening?
Try replacing the defaultValue with value or remove it completely
I have a view with some TextInputs, and some of them are in the bottom part of the screen. The thing is I want the screen to move up when I click on them to that way I can see what I'm writing. I searched a lot but nothing works for me, I have my view nested in a KeyboardAvoidingView but nothing happens when I click on the TextInput. Here's my code:
<KeyboardAvoidingView
keyboardVerticalOffset={64}
style={{ flex: 1 }}
>
<View style={styles.screen}>
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<TextInput
value={title}
onChangeText={text => setTitle(text)}
style={styles.singleLineTextInput}
placeholder="Title"
/>
<TextInput
value={keywords}
onChangeText={text => setKeywords(text)}
style={styles.singleLineTextInput}
placeholder="Keywords"
/>
<TextInput
value={description}
onChangeText={text => setDescription(text)}
style={{ ...styles.singleLineTextInput, ...styles.descriptionTextInput }}
placeholder="Description"
multiline={true}
autoFocus={true}
/>
</TouchableWithoutFeedback>
</View>
</KeyboardAvoidingView >
And my styles:
const styles = StyleSheet.create({
screen: {
flex: 1,
padding: 16,
alignItems: 'center'
},
singleLineTextInput: {
width: DEVICE_WIDTH * 0.8,
borderColor: 'black',
borderBottomWidth: 2,
fontSize: 16,
paddingHorizontal: 16
},
descriptionTextInput: {
maxHeight: DEVICE_HEIGHT / 4
}
});
I'm using React-Navigation and I tried changing keyboardVertialOffset and behavior to multiples values but nothing happens. Any ideas?
Thanks in advance
Import Content from native-base as
import { Content } from 'native-base';
And import platform from react-native
import { Platform } from 'react-native';
And use content and platform in your code like this:
<KeyboardAvoidingView
behavior={Platform.Os == "ios" ? "padding" : "height"}
style={{ flex: 1 }}
><Content>
<View style={styles.screen}>
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<TextInput
value={title}
onChangeText={text => setTitle(text)}
style={styles.singleLineTextInput}
placeholder="Title"
/>
<TextInput
value={keywords}
onChangeText={text => setKeywords(text)}
style={styles.singleLineTextInput}
placeholder="Keywords"
/>
<TextInput
value={description}
onChangeText={text => setDescription(text)}
style={{ ...styles.singleLineTextInput, ...styles.descriptionTextInput }}
placeholder="Description"
multiline={true}
autoFocus={true}
/>
</TouchableWithoutFeedback>
</View>
</Content>
</KeyboardAvoidingView>
Hope this helps!
I'm building a custom header. onPress event of the touchable opacity component is not working when I give components style prop - 'position:"absolute"' . But it works perfectly when I comment on the style property - position.
I couldn't find a solution for this elsewhere. Please help.
<Animated.View
style={{
elevation:
params !== undefined && params.elevation !== undefined
? params.elevation
: null,
position: "absolute",
top: 0,
left: 0,
backgroundColor:
params !== undefined && params.headerBgColor !== undefined
? params.headerBgColor
: "red",
width: "100%",
height:
params !== undefined && params.changingHeight !== undefined
? params.changingHeight
: 50,
justifyContent: "space-between",
alignItems: "center",
flexDirection: "row",
paddingHorizontal: 20
}}
>
<TouchableOpacity style={{}} onPress={() => console.log("hello")}>
<View style={{}}>
<Image
style={styles.menuIcon}
source={require("../../assets/images/Menu-512.png")}
/>
</View>
</TouchableOpacity>
<TouchableOpacity onPress={() => console.log("image")}>
<View style={{}}>
<Image
style={styles.profImage}
source={require("../../assets/images/user.png")}
/>
</View>
</TouchableOpacity>
</Animated.View>;
You should put your absolutely positioned Animated.View as the last child in the screen component. Otherwise, the view that occupies the rest of the screen will become the responder to touches.
const Screen = () => {
return <View style={{ flex: 1}}>
<View style={{flex: 1}}>
//actual screen content
</View>
<Animated.View // header
...props
></Animated.View>
</View>
In the DOM, the component that comes after another component is put "above" it. So, if you do this, your header will be above the actual screen content view and, therefore, become the responder when pressed.
its working on my case checkout below code:
or checkout my snack example : https://snack.expo.io/#immynk/header_demo
either you missing some params which are providing or getting null on condition check kindly confirm it hope this answer will help you
import * as React from 'react';
import {
Text,
View,
StyleSheet,
Animated,
TouchableOpacity,
Image,
} from 'react-native';
import Constants from 'expo-constants';
export default class App extends React.Component {
render() {
return (
<View>
<Text>Hello this is demo of flexdirection of box color</Text>
<Animated.View
style={{
position: 'absolute',
top: 0,
left: 0,
backgroundColor: 'red',
width: '100%',
height: 50,
justifyContent: 'space-between',
alignItems: 'center',
flexDirection: 'row',
paddingHorizontal: 20,
}}>
<TouchableOpacity style={{}} onPress={() => alert("hello","hello")}>
<View style={{}}>
<Image
source={{ uri: 'https://reactjs.org/logo-og.png' }}
style={{ width: 50, height: 65 }}
/>
</View>
</TouchableOpacity>
<TouchableOpacity style={{}} onPress={() => alert("hello","hello")}>
<View style={{}}>
<Image
source={{ uri: 'https://reactjs.org/logo-og.png' }}
style={{ width: 50, height: 65 }}
/>
</View>
</TouchableOpacity>
</Animated.View>
</View>
);
}
}
My app has a homescreen built out of hexagons. Since flex doesn't handle diagonal alignment well I used the transform prop to move the hexagons manually into alignment. However, when the app is re-rendered, the hexagons seem to disappear and reappear at random. It usually takes ~8 renders and then the hexagons will all magically reappear.
EDIT: The invisible hexagons can still be pressed, and when the user navigates back to the homescreen, all the hexagons are visible.
import React, { Component } from 'react';
import { StyleSheet, Text, View, Image, Dimensions, TouchableOpacity } from 'react-native';
class Home extends Component {
constructor(props){
super(props);
}
render() {
return (
<View style={style.columnHexView}>
<View>
<TouchableOpacity
activeOpacity = {.5}
style={style.HexOpacity}
>
<Image style={style.Hex}source={require('./images/logo.png')} />
</TouchableOpacity>
</View>
<View>
<TouchableOpacity
activeOpacity = {.5}
style={style.HexOpacity}
>
<Image style={style.Hex}source={require('./images/emptyhex.png')}/>
</TouchableOpacity>
</View>
<View style={{transform:([
{translateY:(Dimensions.get('window').height/10)*-2.5},
{translateX:(Dimensions.get('window').height/10)*-.84}
])}}>
<TouchableOpacity
activeOpacity = {.5}
style={style.HexOpacity}
onPress={() => this.props.navigation.navigate("documentList")}
>
<Image style={style.Hex}source={require('./images/documenthex.png')} />
</TouchableOpacity>
</View>
<View style={{transform:([
{translateY:(Dimensions.get('window').height/10)*-3.5},
{translateX:(Dimensions.get('window').height/10)*.84}
])}}>
<TouchableOpacity
activeOpacity = {.5}
style={style.HexOpacity}
onPress={() => this.props.navigation.navigate("Settings")}
>
<Image style={style.Hex}source={require('./images/cog.png')} />
</TouchableOpacity>
</View>
<View style={{transform:([
{translateY:(Dimensions.get('window').height/10)*-5}
])}}>
<TouchableOpacity
activeOpacity = {.5}
style={style.HexOpacity}
onPress={() => this.props.navigation.navigate("ToDo")}
>
<Image style={style.Hex}source={require('./images/todohex.png')}/>
</TouchableOpacity>
</View>
<View style={{transform:([
{translateY:(Dimensions.get('window').height/10)*-4.5},
{translateX:(Dimensions.get('window').height/10)*.84}
])}}>
<TouchableOpacity
activeOpacity = {.5}
style={style.HexOpacity}
>
<Image style={style.Hex}source={require('./images/emptyhex.png')}/>
</TouchableOpacity>
</View>
<View style={{transform:([
{translateY:(Dimensions.get('window').height/10)*-5.5},
{translateX:(Dimensions.get('window').height/10)*-.84}
])}}>
<TouchableOpacity
activeOpacity = {.5}
style={style.HexOpacity}
>
<Image style={style.Hex}source={require('./images/emptyhex.png')}/>
</TouchableOpacity>
</View>
</View>
);
}
}
const style = StyleSheet.create({
columnHolder: {
flex: 0,
height: Dimensions.get('screen').height,
width: Dimensions.get('screen').width,
backgroundColor: '#424242',
flexDirection: 'row',
},
columnHexView: {
backgroundColor:'#424242',
alignItems: "center",
justifyContent: 'center',
flex: 1,
},
Hex: {
aspectRatio: 100/85,
maxHeight: Dimensions.get('window').height/10,
resizeMode: 'contain',
flexDirection: 'column',
flex: 0,
flexWrap: 'wrap'
},
hexHold:{
},
HexOpacity: {
justifyContent: 'center',
resizeMode: 'stretch',
display: 'flex',
maxHeight: Dimensions.get('window').height/5
}
}
)
export default Home
In case anyone sees this, the solution was to use cover resize mode instead of contain. I suspect that it was only rendering some hexagons due to slight overlap in between the hexagons.
I’m setting up a new component,
and the keyboard covers the fields
This is for a new component
<KeyboardAwareScrollView enableOnAndroid={true} extraScrollHeight={50} enableAutomaticScroll={true}>
<View style={{ paddingHorizontal: 20 }}>
<View>
<FloatingLabelInput
onRef={(ref) => {
this.inputs['firstName'] = ref
}}
onSubmitEditing={() => {
this.focusNextField('lastName')
}}
label={i18n.t('t_driver_registration_first_name_label')}
onChangeText={(text) => this.onChangeInputText('firstName', text)}
keyboardType='default'
maxLength={20}
value={form.firstName}
labelStyle={Style.inputLabel}
basicColor={GStyle.GREEN}
inputTextColor={Color(GStyle.BLACK).alpha(.7)}
editable={mode !== DriverFormMode.EDIT}
/>
I expect the keyboard will not cover my fields.
Wrap your view in this to scroll automatically on input focus. Do:
<KeyboardAvoidingView style={{ flex: 1, flexDirection: 'column',justifyContent: 'center',}} behavior="padding" enabled keyboardVerticalOffset={100}>
<ScrollView>
<View style={Styles.row}>
//your view
</View>
</ScrollView>
</KeyboardAvoidingView>
<View style={Styles.row}> This is just a Stylesheet e.g. Create a new StyleSheet:
const Styles = StyleSheet.create({
row: {
borderRadius: 4,
borderWidth: 0.5,
borderColor: '#d6d7da',
},
title: {
fontSize: 19,
fontWeight: 'bold',
},
activeTitle: {
color: 'red',
},
});
Use a StyleSheet:
<View style={Styles.row}>
<Text style={[Styles.title, this.props.isActive && styles.activeTitle]} />
</View>