Slide up fixed footer with input text when keyboard appears - keyboard

I'm trying to slide up some part of my app.
I searched for some info and I found out this post here in Stackoverflow -> How to auto-slide the window out from behind keyboard when TextInput has focus?
The thing is that my app is a little bit different and I don't know where to put the Scrollview tags.
I got this distribution:
<View style={ styles.container }>
<View style={ styles.header }>
<View style={ styles.headerTextContainer }>
<Text style={ styles.headerText } onPress={() => this.refs.listView.getScrollResponder().scrollTo(0) }>Parte { this.props.partNumber } - { this.state.totalComments } comentarios</Text>
</View>
</View>
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderComment}
style={ styles.content }
ref="listView" />
<View style={ styles.footer }>
<View style={ styles.footerTextInputContainer }>
<TextInput
style={ styles.footerTextInput }
onChangeText={(text) => console.log(text) }
placeholder="Escribe un comentario" />
</View>
<TouchableHighlight onPress={() => console.log("SEND COMMENT") } underlayColor="#ffffff">
<View style={ styles.footerSendButtonContainer }>
<Text style={ styles.footerSendButton }>Enviar</Text>
</View>
</TouchableHighlight>
</View>
</View>
The only thing I want to slide up when keyboard appears is the footer View.
I hope someone can help me out.
Thank you :)

I was be able to do it by using this component: react-native-keyboard-spacer
Thanks!

This is my solution:
const [keyboardHeight, setKeyboardHeight] = useState("10%");
useEffect(() => {
const keyboardDidShowListener = Keyboard.addListener(
'keyboardDidShow',
() => {
setKeyboardHeight("15%"); // or some other action
}
);
const keyboardDidHideListener = Keyboard.addListener(
'keyboardDidHide',
() => {
setKeyboardHeight("10%"); // or some other action
}
);
return () => {
keyboardDidHideListener.remove();
keyboardDidShowListener.remove();
};
}, []);
And in the view:
<View style={[globalStyles.footer, {height: keyboardHeight}]}>
//PUT YOUR VIEW FOOTER HERE
</View>

Related

navigation.navigate does not change scene

I've been trying to work with this since yesterday, tried different methods and none actually worked. I'm currently using a drawer navigator, tab navigator and I want to open a different scene when clicking a icon.
Here is the current design:
The icon I want to open a new scene is the "filter" up on the top-right corner.
My current header code is:
<Header>
<Left>
<Icon name='ios-menu' style={{ color: 'white' }} onPress={() =>
this.props.navigation.dispatch(DrawerActions.openDrawer())} />
</Left>
<View style={{ width: Dimensions.get('window').width * 0.7 }}>
<Text style={styles.headerTextTop}>Estabelecimentos</Text>
</View>
<Right>
<Icon name='ios-search' style={{ paddingRight: 20, color: 'white' }} />
<Icon name='ios-options' style={{ color: 'white' }} onPress={this.openFilter} />
</Right>
</Header>
and here is the function openFilter:
openFilter = () =>
{
this.props.navigation.navigate('Filter');
}
I'm importing the filter component from its .js file, I can't get it to switch scenes.
Here is the Filter.js (which i'm importing as import Filter from './Filter'):
import React, { Component } from "react";
import {
View,
Text,
Dimensions
} from "react-native";
import { Icon, Header, Left, Right } from 'native-base'
class Filter extends Component {
render() {
return (
<View>
<Header>
<Left>
<Icon name='ios-arrow-back' style={{color: 'white'}} onPress={() =>
this.props.navigation.goBack()} />
</Left>
<View style={{ width: Dimensions.get('window').width * 0.7 }}>
<Text style={sty.headerTextTop}>Filtro</Text>
</View>
<Right>
</Right>
</Header>
</View>
);
}
}
export default Filter;
--EDIT:--
As #Pritish Vaidya suggested, I should implement a Stack Navigator, so I made one:
import { StackNavigator} from 'react-navigation'
import Filter from './Filter';
import App from './App';
import Home from './Home';
const stackNav = StackNavigator({
App: {
screen: App,
navigationOptions:({navigation}) => ({
title: "Main",
headerStyle: { paddingRight: 10, paddingLeft: 10 }
})
},
Filter: {
screen: Filter,
navigationOptions: (props) => ({
title: "Filtro",
})
},
Home: {
screen: Home,
navigationOptions: (props) => ({
title: "Home",
})
}
})
export default stackNav;
But in Home.js when I call navigate using:
<Icon name='ios-options' style={{ color: 'white' }} onPress={() => this.props.navigator.navigate("Filter")} />
It gets me this error:

How to use ScrollView with third party Components in React Native?

Very simple, how can I use ScrollView when using an third party (react-native-elements) List/List-Items? The given docs does not inform this: link
The list is fully working, but can't be scrolled:
Here is the code for rendering the list:
<View style={{ flex: 1 }}>
<List>
{
list.map((l, i) => (
<ListItem
roundAvatar
key={i}
title={l.name}
subtitle={
<View>
<View style={styles.subtitleView}>
<Text style={styles.ratingText}>{l.subtitle}</Text>
</View>
</View>
}
avatar={<Avatar
medium
rounded
source={l.avatar_url && { uri: l.avatar_url }}
title={l.name[0]}
/>}
/>
))
}
</List>
</View>
If I simply change the View to ScrollView, that should be the obvious move, I get this error:
I'm importing ScrollView from native-base and the List from react-native-elements.
Try to make the ScrollView under your View, also add additional View (not required) under the ScrollView.
<View style={{ flex: 1 }}>
<ScrollView>
<View>
<List>
{
list.map((l, i) => (
<ListItem
roundAvatar
key={i}
title={l.name}
subtitle={
<View>
<View style={styles.subtitleView}>
<Text style={styles.ratingText}>{l.subtitle}</Text>
</View>
</View>
}
avatar={<Avatar
medium
rounded
source={l.avatar_url && { uri: l.avatar_url }}
title={l.name[0]}
/>}
/>
))
}
</List>
</View>
</ScrollView>
</View>
Also consider using FlatList rather than ScrollView for better performance.
Reference:
https://facebook.github.io/react-native/docs/scrollview
https://facebook.github.io/react-native/docs/flatlist

How can I set my view to take top half of the screen for react-native android app?

I want to set my <View> to take only the top half of the screen. If I set flex:1 on the view's style, it will take the full screen. See below code:
render(){
return(
<View style={{flex:1}}>
...
</View>
);
}
I have tried to set the flex value to 0.5 but it doesn't help. How can I set my view takes half of the screen on flexbox?
render(){
return(
<View style={{flex:1}}>
<View style={{flex:.5}}>
...
</View>
<View style={{flex:.5}}/>
</View>
);
}
try this code:
<View style={{flex: 1,flexDirection:'row'}}>
<View style={{flex: 2, backgroundColor: 'powderblue',height:100}} />
<View style={{flex: 2, backgroundColor: 'skyblue',height:100}} />
</View>
Try this:
import {Dimensions, StyleSheet, View} from 'react-native';
const height = Dimensions.get('window').height*0.5;
const width = Dimensions.get('window').width;
const styles = StyleSheet.create({
container: {
width,
height
}
)};
render(){
return(
<View style={styles.container}>
...
</View>
);
}
Another way is you can use the Dimensions API to check the Height of the device and set the component height to half and position absolute: Dimensions

How to get the text from the Text Component within TouchableHighlight Component?

How can I get the text content from the Text Component within TouchableHighlight Component when clicked the TouchableHighlight component? Give me some idea to write the handleClickMenu function, thanks.
some code as following:
<View>
<TouchableHighlight underlayColor='#544b44' onPress={this.handleClickMenu}>
<View style={MenuListStyle.menuItem}>
<Icon name='heart' color='#df7454' style={MenuListStyle.menuItemIcon}/>
<Text style={MenuListStyle.menuItemText}>GODDESS</Text>
</View>
</TouchableHighlight>
<TouchableHighlight underlayColor='#544b44' onPress={this.handleClickMenu}>
<View style={MenuListStyle.menuItem}>
<Icon name='rss' color='#03a9f4' style={MenuListStyle.menuItemIcon}/>
<Text style={MenuListStyle.menuItemText}>BLOG</Text>
</View>
</TouchableHighlight>
...
</View>
You can use bind to pass additional argument. In this case MenuListStyle.menuItemText that you can get in handleClickMenu
handleClickMenu(text){
if(text === <something>){
//do something
}
}
render(){
...
<View>
<TouchableHighlight underlayColor='#544b44' onPress={this.handleClickMenu.bind(this, MenuListStyle.menuItemText)}>
<View style={MenuListStyle.menuItem}>
<Icon name='heart' color='#df7454' style={MenuListStyle.menuItemIcon}/>
<Text style={MenuListStyle.menuItemText}>GODDESS</Text>
</View>
</TouchableHighlight>
<TouchableHighlight underlayColor='#544b44' onPress={this.handleClickMenu.bind(this, MenuListStyle.menuItemText)}>
<View style={MenuListStyle.menuItem}>
<Icon name='rss' color='#03a9f4' style={MenuListStyle.menuItemIcon}/>
<Text style={MenuListStyle.menuItemText}>BLOG</Text>
</View>
</TouchableHighlight>
...
</View>
}

React Native: issue with flex layout

I'm trying to make a simple view with 2 subviews - v1, v2 aligned horizontally and each taking 50% of the screen width.
To achieve this, I'm using the following code:
<View style={{flexDirection: 'row'}}>
<View style={{flex:1}}>
<View style={{flex:1}}>
</View>
I've also tried playing with other attributes- flexWrap, justifyContent.
However, everytime the views get stacked one after the other and doesn't take 50% of the screen. What am I doing wrong?
EDIT: The actual piece of code I'm using:
<View>
<Text style={styles.place}>New Delhi</Text>
<View style={{flexDirection: 'row'}}>
<DayTimeComponent style={{flex:1}}/>
<DayTimeComponent style={{flex:1}}/>
</View>
</View>
You can achieve this easily using react-native-easy-grid
Code:
import { Col, Row, Grid } from "react-native-easy-grid";
export default class StackOverflow extends Component {
render() {
return (
<View style={{flex:1}}>
<Grid>
<Col style={{backgroundColor:'yellow',alignItems:'center',justifyContent:'center'}}><Text>v1</Text></Col>
<Col style={{backgroundColor:'green',alignItems:'center',justifyContent:'center'}}><Text>v2</Text></Col>
</Grid>
</View>
);
}
}
Result:
You can also create custom layouts, for eg: if you need a 75%-25% split then all you need to do is
<Col size={75}></Col>
<Col size={25}></Col>
Set "flex:1" on both the container views. Like so:
<View style={{flex:1}}>
<Text style={styles.place}>New Delhi</Text>
<View style={{flexDirection: 'row', flex:1}}>
<DayTimeComponent style={{flex:1}}/>
<DayTimeComponent style={{flex:1}}/>
</View>
</View>

Resources