I'm trying to display the [DrawerLayoutAndroid][1] component of React Native:
/**
* Sample React Native App
* https://github.com/facebook/react-native
*/
'use strict'
import React, {
AppRegistry,
Component,
StyleSheet,
Text,
TextInput,
View,
ScrollView,
DrawerLayoutAndroid
} from 'react-native'
class Dictionary extends Component {
constructor(props) {
super(props)
this.state = {
movies: 'Test'
}
}
render() {
const navigationView = (
<View style={{flex: 1, backgroundColor: '#fff'}}>
<Text style={{margin: 10, fontSize: 15, textAlign: 'left'}}>Im in the Drawer!</Text>
</View>
)
return (
<ScrollView>
<DrawerLayoutAndroid
drawerWidth={300}
drawerPosition={DrawerLayoutAndroid.positions.Left}
renderNavigationView={() => navigationView}>
<View style={{flex: 1, alignItems: 'center'}}>
<Text style={{margin: 10, fontSize: 15, textAlign: 'right'}}>Hello</Text>
<Text style={{margin: 10, fontSize: 15, textAlign: 'right'}}>World!</Text>
</View>
</DrawerLayoutAndroid>
<View style={styles.parent}>
<Text>
Type something in English:
</Text>
<TextInput/>
<Text style={styles.germanLabel}>
Movies: { this.state.movies }
</Text>
</View>
</ScrollView>
)
}
}
const styles = StyleSheet.create({
parent: {
padding: 16
},
germanLabel: {
marginTop: 20,
fontWeight: 'bold'
},
germanWord: {
marginTop: 15,
fontSize: 30,
fontStyle: 'italic'
}
})
AppRegistry.registerComponent('Dictionary', () => Dictionary)
However, the app doesn't display anything:
What could be the cause? (There aren't any error messages either, seems like everything compiled just fine.)
Try to make your DrawerLayoutAndroid as a root node. There is no information about this in docs, but helped me. Does this helps you?
Related
I have stored the value locally using array, And I want to delete a single item by using Trash icon. But I need to delete the multi selected items from the array.
So I placed the button "Delete selected". But I am not able to select multiple items and I don't know how to write the functionality to delete multiple items. I'm new for the React Native so kindly help.
Here is my code
import React, { Component } from "react"
import { View, Text, TouchableOpacity, TouchableHighlight, TextInput, StyleSheet, FlatList,onRemove } from 'react-native'
import {Card,CardItem,Right} from 'native-base';
import Swipeout from 'react-native-swipeout'
import Icon from 'react-native-vector-icons/FontAwesome';
import MultiSelect from 'react-native-multiple-select';
class Screen3 extends Component{
constructor(props) {
super(props);
this.state = {
loading: false,
firstname:[],
onPress:true,
unique1:[],
unique:[],
selectedItems : [],
renderData:item,
key1:0
};
}
componentDidMount=()=>{
const{navigation}=this.props
const data=navigation.getParam('data','')
const unique=data.filter((value,index,self)=>self.indexOf(value)===index)
var key=0
const unique1=[]
for(var i=0;i<unique.length;i++){
key=key+1
var result={"name":unique[i],"key":key}
this.state.unique1.push(result)
this.state.key1=this.state.key1+1
this.setState({key1:this.state.key1})
}
}
onPressHandler(item) {
let renderData=[...this.state.renderData];
for(let data of renderData){
if(data.item==item){
data.selected=(data.selected==null)?true:!data.selected;
break;
}
}
this.setState({renderData});
}
deleteItem = (item,index) => {
console.log(item.name,index)
this.state.unique=this.state.unique1
let filtered=this.state.unique.filter((item1) => item1.key !== item.key)
console.log(filtered)
this.setState({unique1:filtered})
}
render(){
return (
<View>
<Text style={styles.heading}>
Manage Screen
</Text>
<TouchableOpacity style = {styles.Button}
onPress={()=>this.deleteItem(item,index) } >
<Text style={styles.button}>Delete selected</Text>
</TouchableOpacity>
<FlatList
data={this.state.unique1}
showsVerticalScrollIndicator={false}
extraData={this.state.key1}
style={{ marginTop: 16 }}
renderItem={({ item, index }) => (
// <TouchableOpacity onPress={() => this.handleData(item)}>
<TouchableOpacity onPress={() => this.onPressHandler(item,index)}>
item!=null?
<Card
style={{
elevation: 10,
marginBottom: 15,
}}
>
<View style={{ flex: 1 }}></View>
<CardItem bordered >
style={
item.selected==true
? {
padding: 10,
borderRadius: 5,
backgroundColor: '#000000',
}
: {
borderRadius: 5,
backgroundColor: '#a1a1a1',
}}
<Text>{item.name}</Text>
<Right style={{alignSelf:'flex-end' } }>
<TouchableOpacity onPress={() => this.deleteItem(item,index)}>
<Icon size={25} name={Platform.OS ==='android' ? "trash" : "ios-trash"} color="red"/>
</TouchableOpacity>
</Right>
</CardItem>
</Card>:null
// </TouchableOpacity>
)
}
/>
</View>
)
}
}
export default Screen3
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
heading: {
fontSize: 23,
paddingVertical:80,
textAlign: 'center',
marginBottom: 30,
marginTop: -40,
},
button:{
width:('39%'),
height:('4%'),
alignItems:'center',
borderWidth:1,
borderRadius:2,
marginTop:-80,
marginHorizontal:10,
marginLeft:110,
justifyContent:'center',
backgroundColor: '#b0c4de',
padding: 9,
fontSize: 15,
margin: 15,
height: 40,
width: 160,
alignItems: 'center'
}
}
)
You would need a different function to delete multiple items and that function would call your deleteItem() function. A simple, but not so efficient way would be to loop through your selectedItems and find them in your data array and then remove each selected item with deleteItem(). You can then improve from there if it's not efficient enough.
I'm using react-navigation version 5, currently, I have a screen with Text and Button inside a View which placed at the top of the SafeAreaView, and I need to add TopTabNavigator just below the View.
Here's the code:
TimelineComponent.js
import React from 'react';
import PropTypes from 'prop-types';
import {ScrollView, Text} from 'react-native';
class TimelineComponent extends React.PureComponent {
render() {
return (
<ScrollView>
<Text>Timeline</Text>
</ScrollView>
);
}
}
export default TimelineComponent;
TrendingComponent.js
import React from 'react';
import PropTypes from 'prop-types';
import {ScrollView, Text} from 'react-native';
class TrendingComponent extends React.PureComponent {
render() {
return (
<ScrollView>
<Text>Trending</Text>
</ScrollView>
);
}
}
export default TrendingComponent;
TopNav.js
import React from 'react';
import {createMaterialTopTabNavigator} from '#react-navigation/material-top-tabs';
import TimelineComponent from '../TimelineComponent';
import TrendingComponent from '../TrendingComponent';
const Tab = createMaterialTopTabNavigator();
export function TopNav() {
return (
<Tab.Navigator>
<Tab.Screen name="Timeline" component={TimelineComponent} />
<Tab.Screen name="Trending" component={TrendingComponent} />
</Tab.Navigator>
);
}
WallFragmentComponent.js
import React from 'react';
import PropTypes from 'prop-types';
import Icon from 'react-native-vector-icons/FontAwesome';
import {
Keyboard,
SafeAreaView,
StyleSheet,
Text,
TouchableOpacity,
TouchableWithoutFeedback,
View,
} from 'react-native';
import {TopNav} from './TopNav';
const styles = StyleSheet.create({
container: {
padding: 20,
},
header_container: {
backgroundColor: 'white',
alignItems: 'center',
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
},
header_text: {
fontSize: 30,
fontWeight: '500',
},
new_chat_button: {
alignItems: 'center',
borderColor: 'blue',
borderWidth: 1,
borderRadius: 12,
display: 'flex',
flexDirection: 'row',
paddingHorizontal: 22,
paddingTop: 6,
paddingVertical: 6,
},
top_nav: {
marginVertical: 20,
},
});
class WallFragmentComponent extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
input: {},
secureTextEntry: true,
};
}
handleInput = (name, value) => {
this.setState({
input: {...this.state.input, [name]: value},
});
};
render() {
return (
<View style={{backgroundColor: 'white'}}>
<SafeAreaView>
<TouchableWithoutFeedback
onPress={Keyboard.dismiss}
accessible={false}>
<View style={styles.container}>
<View style={styles.header_container}>
<Text style={styles.header_text}>Wall</Text>
<TouchableOpacity style={styles.new_chat_button}>
<Icon name="comment" style={{marginEnd: 6, color: 'blue'}} />
<Text style={{fontWeight: '500', color: 'blue'}}>
New Post
</Text>
</TouchableOpacity>
</View>
</View>
</TouchableWithoutFeedback>
<View style={styles.top_nav}>
<TopNav />
</View>
</SafeAreaView>
</View>
);
}
}
export default WallFragmentComponent;
In the WallFragmentComponent.js file, I have placed <TopNav /> inside a View, but it's not rendering when I run the project. Here's the screenshot:
screenshot
How am I able to add top navigation just under the Wall Text and New Post button? any help will be much appreciated.
Thank you,
Regards
This might help
// TopNav.js
const Tab = createMaterialTopTabNavigator();
const AppNavigator = () => {
return (
<Tab.Navigator>
<Tab.Screen name="Timeline" component={TimelineComponent} />
<Tab.Screen name="Trending" component={TrendingComponent} />
</Tab.Navigator>
)
}
export default AppNavigator;
WallFragmentComponent.js
import AppNavigator from './AppNavigator';
...........
const TopNav = createAppContainer(AppNavigator);
class WallFragmentComponent extends React.PureComponent {
......
render() {
return (
<View style={{backgroundColor: 'white'}}>
......
<TopNav />
......
</View>
);
}
}
You can also use react-native-scrollable-tab-view
Well, finally I have found the solution:
Change the first <View ... /> element into <SafeAreaView style={{flex: 1}} /> and then everything is working correctly.
WallFragmentComponent.js
import React from 'react';
import PropTypes from 'prop-types';
import Icon from 'react-native-vector-icons/FontAwesome';
import {
Keyboard,
SafeAreaView,
StyleSheet,
Text,
TouchableOpacity,
TouchableWithoutFeedback,
View,
} from 'react-native';
import {TopNav} from './TopNav';
const styles = StyleSheet.create({
container: {
padding: 20,
},
header_container: {
backgroundColor: 'white',
alignItems: 'center',
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
},
header_text: {
fontSize: 30,
fontWeight: '500',
},
new_chat_button: {
alignItems: 'center',
borderColor: 'blue',
borderWidth: 1,
borderRadius: 12,
display: 'flex',
flexDirection: 'row',
paddingStart: 22,
paddingEnd: 22,
paddingTop: 6,
paddingBottom: 6,
},
top_nav: {
marginTop: 20,
},
});
class WallFragmentComponent extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
input: {},
secureTextEntry: true,
};
}
handleInput = (name, value) => {
this.setState({
input: {...this.state.input, [name]: value},
});
};
render() {
return (
<SafeAreaView style={{flex: 1, backgroundColor: 'white'}}>
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
<View style={styles.container}>
<View style={styles.header_container}>
<Text style={styles.header_text}>Wall</Text>
<TouchableOpacity style={styles.new_chat_button}>
<Icon name="comment" style={{marginEnd: 6, color: 'blue'}} />
<Text style={{fontWeight: '500', color: 'blue'}}>
{' '}
New Post
</Text>
</TouchableOpacity>
</View>
</View>
</TouchableWithoutFeedback>
<TopNav />
</SafeAreaView>
);
}
}
export default WallFragmentComponent;
Screenshot
And that's it
I am making a react native app and for some reason when I tap on the text input to type something it disappears under the keyboard. I want it to come to the top of the keyboard like the way Instagram messenger and other messenger apps do it. I tried using keyboardAvoidView and setting the behavior to padding and height but none of it worked.
import {
View,
Text,
StyleSheet,
SafeAreaView,
TextInput,
TouchableOpacity,
} from "react-native";
import CommunityPost from "../components/CommunityPost";
import { Context as CommunityContext } from "../context/CommunityContext";
const Key = ({ navigation }) => {
const { createCommunityPost, errorMessage } = useContext(CommunityContext);
const [body, setBody] = useState("");
return (
<View style={styles.container}>
<SafeAreaView />
<CommunityPost />
<View style={styles.inputContainer}>
<TextInput
style={styles.input}
multiline={true}
placeholder="Type..."
placeholderTextColor="#CACACA"
value={body}
onChangeText={setBody}
/>
<TouchableOpacity
style={{ justifyContent: "center", flex: 1, flexDirection: "row" }}
onPress={() => createCommunityPost({ body })}
>
<Text style={styles.sendText}>Send</Text>
</TouchableOpacity>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "flex-start",
backgroundColor: "#2B3654",
justifyContent: "flex-end",
},
inputContainer: {
justifyContent: "flex-end",
flexDirection: "row",
},
sendText: {
color: "white",
fontSize: 25,
},
input: {
fontSize: 25,
color: "white",
borderColor: "#2882D8",
borderWidth: 1,
borderRadius: 15,
width: "80%",
marginBottom: 30,
marginLeft: 10,
padding: 10,
},
});
export default Key;
You must KeyboardAvoidingView component provided by react native.
<KeyboardAvoidingView
behavior={Platform.OS == "ios" ? "padding" : "height"}
style={styles.container}
>
<SafeAreaView />
<CommunityPost />
<View style={styles.inputContainer}>
<TextInput
style={styles.input}
multiline={true}
placeholder="Type..."
placeholderTextColor="#CACACA"
value={body}
onChangeText={setBody}
/>
<TouchableOpacity
style={{ justifyContent: "center", flex: 1, flexDirection: "row" }}
onPress={() => createCommunityPost({ body })}
>
<Text style={styles.sendText}>Send</Text>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
For these situations we can use one of these methods:
1.wrapping Component with <ScrollView></ScrollView>
2.wrapping Component with <KeyboardAvoidingView></KeyboardAvoidingView>
Sometimes our wrong given styles can make these happens too such as : Having a fixed value for our styles, check your margins and use one of the given methods
I hope it helps
Try using keyboardVerticalOffset and test it with different values.
For more info check this out
For those who want to keep the code clean, just use the FlatList component and add a View component involving the component with the states: {flex: 1, height: Dimensions.get ("window"). Height}.
Below left a component ready for anyone who wants to use, just wrap your component in this way:
<FormLayout>
{... your component}
</FormLayout>
Here is the solver component:
import React from 'react'
import { View, StyleSheet, FlatList, Dimensions } from 'react-native'
import Background from './Background'
const FormLayout = ({ children }) => {
const renderContent = <View style={styles.container}>
{children}
</View>
return <FlatList
ListHeaderComponent={renderContent}
showsVerticalScrollIndicator={false}
/>
}
const styles = StyleSheet.create({
container: {
flex: 1,
height: Dimensions.get('window').height * 0.95
}
})
export default FormLayout
I was trying to make a "photo galley app" where each image is a "button" that toggle on the boolean property for Modal tag. The problem is that the images are rendered by a FlatList which pass props to component "GenerateImage.js", but at the same time, I need to pass the state and dispatch function as a parameter as well.
File who render the FlatList:
import React, { Component } from 'react'
import { FlatList, View, StyleSheet, TouchableOpacity, Text, AppRegistry } from 'react-native'
import { connect } from 'react-redux'
import GenerateImage from '../components/GenerateImage'
import commonStyles from '../commonStyles'
import Modal from '../components/Modal'
const Photos = ({ params }) => {
return (
<View style={{ flex: 1 }}>
<Modal isVisible={params.showFullImage} />
<View style={styles.buttonsContainer}>
<TouchableOpacity style={styles.touchContainer}>
<Text style={styles.button}>Hoje</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.touchContainer}>
<Text style={styles.button}>Mês</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.touchContainer}>
<Text style={styles.button}>Ano</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.touchContainer}>
<Text style={styles.button}>Álbuns</Text>
</TouchableOpacity>
</View>
<View style={{ flex: 30 }}>
<FlatList data={params.images} keyExtractor={item => `${item.id}`}
renderItem={({item}) => <GenerateImage {...item} />} numColumns={2} />
</View>
</View>
)
}
const styles = StyleSheet.create({
buttonsContainer: {
flex: 3,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#1c2431',
},
touchContainer: {
marginHorizontal: 20,
backgroundColor: '#439ce8',
borderRadius: 30,
width: 65,
alignItems: 'center',
justifyContent: 'center',
padding: 5
},
button: {
color: 'white',
fontFamily: commonStyles.Font,
fontSize: 14
}
})
export default connect(state => ({ params: state[0] }))(Photos)
GenerateImage.js:
import React from 'react'
import { View,
StyleSheet,
Image,
PixelRatio,
Dimensions,
TouchableOpacity } from 'react-native'
import { connect } from 'react-redux'
const GenerateImage = (props, {param, dispatch}) => {
function toggleModal(param) {
return {
type: 'TOGGLE_MODAL_ON',
}
}
return (
<View style={styles.container}>
<View style={styles.imgContainer}>
<TouchableOpacity activeOpacity={0.7} onPress={() => dispatch(toggleModal(param))}>
<Image source={props.image} style={styles.imgContainer} />
</TouchableOpacity>
</View>
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginVertical: 5,
marginHorizontal: 4
},
imgContainer: {
height: Dimensions.get('window').height * 0.25,
width: Dimensions.get('window').width * 0.48,
//borderRadius: 8,
//flex: 1,
//orderWidth: 1,
},
image: {
resizeMode: 'contain',
aspectRatio: PixelRatio.get()
},
})
export default connect(state => ({ param: state[0].showFullImage }))(GenerateImage)
So, how can I pass both data?
Whenever I click on Email in the first <TextInput/> box on my physical device, I can't see what's being typed. Only when I press Next to go to the Password box do I see what was typed in the Email box. Why's this so?
Here's App.js:
import React, {Component} from 'react';
import {View, StyleSheet} from 'react-native';
import BackGround from './components/BackGround';
export default class App extends Component {
render() {
return(
<View style={styles.back}>
<BackGround/>
</View>
);
}
}
const styles = StyleSheet.create({
back: {
flex: 1
}
});
Here's Login.js:
import React, {Component} from 'react';
import {StyleSheet, TextInput, View, Text, TouchableOpacity, KeyboardAvoidingView} from 'react-native';
class Login extends Component {
constructor(props) {
super(props);
this.state = {
text: ''
};
}
updateTextInput = text => this.setState({text});
render() {
return(
<KeyboardAvoidingView behavior={"padding"} style={styles.container}>
<View>
<TextInput
style={styles.input}
returnKeyType={"next"}
keyboardType={"email-address"}
autoCorrect={false}
onChangeText={this.updateTextInput}
value={this.state.text}
/>
<TextInput
style={styles.input}
returnKeyType={"go"}
secureTextEntry
/>
<TouchableOpacity>
<Text style={styles.loginAndCA}>Login</Text>
</TouchableOpacity>
<TouchableOpacity>
<Text style={styles.loginAndCA}>Create Account</Text>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
);
}
}
const styles = StyleSheet.create({
container: {
padding: 20
},
input: {
backgroundColor: '#DAE5FF',
paddingBottom: 20,
padding: 20,
paddingHorizontal: 15,
marginBottom: 10,
borderRadius: 15,
},
loginAndCA: {
fontSize: 40,
textAlign: 'center',
color: 'white',
fontFamily: 'Bodoni 72 Smallcaps',
paddingHorizontal: 10
},
buttons: {
paddingBottom: 50
}
});
export default Login;
Here's BackGround.js:
import React, {Component} from 'react';
import {StyleSheet, Image, View} from 'react-native';
import Login from './Login';
export default class BackGround extends Component {
render() {
return(
<View style={styles.first}>
<Image style={styles.container} source={require('../pictures/smoke.jpg')}>
<View style={styles.second}>
<Login/>
</View>
</Image>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
width: null,
height: null,
backgroundColor: 'rgba(0,0,0,0)',
resizeMode: 'cover'
},
first: {
flex: 1
},
second: {
paddingTop: 290 // Moves both <TextInput> boxes down.
}
});
You need to pass value and onTextChange props to TextInput.
https://facebook.github.io/react-native/docs/textinput.html
You need to give it a value connected to state and as that textinput changes, you update the state value:
export default class TextInputExample extends Component {
constructor(props) {
super(props);
this.state = {
text: ''
};
}
updateTextInput = text => this.setState({ text })
render() {
return (
<View style={{ flex: 1}}>
<TextInput
style={{height: 40}}
placeholder="Type here!"
onChangeText={this.updateTextInput}
value={this.state.text}
/>
</View>
);
}
}