React Native - place two items side by side - react-native

I'm trying to place an item on the right side of another, but instead it always stays on the bottom of the first item, like this:
So, right now I'm just trying to place the "TEST" text right next to that side menu.
Here's my code:
<View style = {{flex: 1, width: Dimensions.get('window').width,
height: Dimensions.get('window').height}}>
<Workspace
img={require('./images/quarto.png')}/>
<ScrollView>
<Header>
<HeaderItem img={require('./images/camera.png')}/>
<HeaderItem img={require('./images/camera.png')}/>
<HeaderItem img={require('./images/camera.png')}/>
<HeaderItem img={require('./images/camera.png')}/>
</Header>
</ScrollView>
<ScrollView style = {{flexDirection: 'row'}}>
{this.sideMenuShow()}
<ScrollView style = {{alignSelf: 'flex-end'}}>
<Text style = {{color: 'white'}}>TEST</Text>
</ScrollView>
</ScrollView>
<Footer>
<View style = {styles.logoContainerStyle}>
<Image
style = {styles.logoStyle}
source = {require('./images/magicalStage.png')}
/>
</View>
<View
style = {{width: '70%', flexDirection: 'row', justifyContent:'flex-end', alignItems: 'flex-end'}}>
<TouchableOpacity>
<Text style = {{color: 'white'}}>Workspace </Text>
</TouchableOpacity>
<TouchableOpacity>
<Text style = {{color: 'white', textAlign: 'right'}}>Catalogue</Text>
</TouchableOpacity>
</View>
</Footer>
</View>
If it helps, the side menu code is:
sideMenuShow() {
const furnitureList = <FurnitureList />;
if(!this.state.hideMenu) {
return(
<SideMenu>
<MenuButton
source = {require('./images/left-material.png')}
onPress = {() => this.setState({hideMenu: true})}/>
<Text style = {{color: 'white', fontSize: 16, fontWeight: 'bold'}}>Furniture</Text>
<SideMenuItem
onPress = {() =>
!this.state.hideList ?
this.setState({hideList: true, hideListSofa: false, hideListBoxes: false})
: this.setState({hideList: false})
}
text='Test'
>
</SideMenuItem>
{
this.state.hideList ?
<FurnitureList
source = {require('./images/image.png')}/>
: null
}
</SideMenu>
);
}
else {
return(
<SmallSideMenu>
<MenuButton
source = {require('./images/right-material.png')}
onPress = {() => this.setState({hideMenu: false})}/>
</SmallSideMenu>
);
}
}
I thought I'd get what I want by setting the flexDirection of the ScrollView wraping both items to 'row', but it's not working as I thought it would. Any help would be great!

You placed your <Text style = {{color: 'white'}}>TEST</Text> Component inside a ScrollView.
Try to add contentContainerStyle={{ flexDirection: 'row'}} to the parent ScrollView or just remove the parent ScrollView. Hope it helps.

{ flexDirection: 'row' } as mentioned in above answer works.
You need to apply this to parent.
For example:
let's say your HTML equivalent looks like this:
<div class='parent'>
<div class='child1'></div>
<div class='child2'></div>
</div>
then you've to apply flexDirection: 'row' to 'parent' NOT 'child'
This will make child1 and child2 render horizontally next to each other in same line.

Related

Changing a parent state when a child component updates

I have a main component, which has two child components, a flat list and a button group component (from react-native-elements).
I want to update the flat list data when a user taps on one of the button group options, however, I can't really figure this out, I tried to use callbacks, but couldn't really understand how they work, and it didn't work for me.
This is my main component:
return (
<SafeAreaView style={styles.homeContainer}>
<View style={{flex: 1}}>
<View style={styles.headerContainer}>
<View
style={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
}}>
<Text style={styles.title}>Groups</Text>
<Avatar
rounded
source={{
uri: profilePhotoURL,
}}
/>
</View>
<Text style={styles.subtitle}>Find people to learn with</Text>
</View>
<OptionChooser /> {/** <---- this is the button group component*/}
<FlatList
data={meetings}
renderItem={({item}) => (
<TouchableOpacity
style={styles.cardButton}
onPress={() =>
navigation.navigate('MeetingDetails', {meeting: item})
}>
<MeetingCard meetingModel={item} style={{flex: 1}} />
</TouchableOpacity>
)}
keyExtractor={(item) => item.id!}
showsVerticalScrollIndicator={false}
/>
</View>
<FloatingButton onPress={() => navigation.navigate('AddMeeting')} />
</SafeAreaView>
);
And this is my button group (OptionChooser) component:
const OptionChooser = () => {
const [selectedIndex, setSelectedIndex] = useState<number>(0);
const buttons = ['All', 'Today', 'This week'];
const updateIndex = (index) => {
setSelectedIndex(index);
console.log(index);
};
return (
<View style={styles.buttonGroupContainer}>
<ButtonGroup
onPress={updateIndex}
selectedIndex={selectedIndex}
buttons={buttons}
containerStyle={{height: 44, borderRadius: 4}}
selectedButtonStyle={{backgroundColor: '#8BCFB0'}}
/>
</View>
);
};
My goal is whenever updateIndex gets called in OptionChooser, to update the flat list in the parent component.
As you have said, callbacks would be the easiest option to use in the situation.
Lets start with your parent component.
Assume that you have two state variables meetings,selectedIndex
Its always a good idea to make the child component dumb and manage the state in parent rather than managing states in both.
Your parent would have the setSelectedIndex which would update the parent selectedIndex state.
so you pass the state and function to the child like below
<OptionChooser selectedIndex={selectedIndex} setSelectedIndex={setSelectedIndex}/>
And you child component will have to be like this
const OptionChooser = ({selectedIndex,setSelectedIndex}) => {
const buttons = ['All', 'Today', 'This week'];
return (
<View style={styles.buttonGroupContainer}>
<ButtonGroup
onPress={setSelectedIndex}
selectedIndex={selectedIndex}
buttons={buttons}
containerStyle={{height: 44, borderRadius: 4}}
selectedButtonStyle={{backgroundColor: '#8BCFB0'}}
/>
</View>
);
};
And in your render you can simply filter the meetings using this state like below
<FlatList data={meetings.filter(x=>x.type==selectedIndex)} ...
//actual condition may vary according to your need.
So whenever your child changes the changes would be reflected in parent.

How to call a method of a component

I am using native-base datepicker and want to call the ShowDatePicker method from outside the component. It owuld be something like this except:
This.DatePicker doesnt exist
I dont know if that method is exposed, or how to reach it..
i think it has something to do with using refs?
Thank you!
<Content>
<Button onPress={this.DatePicker.showDatePicker}>
<DatePicker props}/>
</Content>
DatePicker source code: https://github.com/GeekyAnts/NativeBase/blob/master/src/basic/DatePicker.js
Well, if you have to ref it just like the another answer says, as follows
<Content>
<Button onPress={this.DatePicker.showDatePicker}>
<DatePicker ref={ref => this.DatePicker = ref } {...this.props}/>
</Content>
However this will not fix your issue unless DatePicker component takes a props as ref. In short, even if you do that in your component, you will not have access to the showDatePicker.
Rather trying to do so, you can do this in two way (assuming you are trying to showhide component on button click.
Option 1:
Use a prop showDatePicker which will show hide the component.
For ex,
<Content>
<Button onPress={this.setState({showHide: !this.state.showHide})}>
<DatePicker showDatePicker={this.state.showHide} {...this.props} />
</Content>
then in DatePicker use this prop to do some logic.
Or Option 2,
Use conditional operator to show hide the whole component. w
For ex,
<Content>
<Button onPress={this.setState({showHide: !this.state.showHide})}>
{this.state.showHide && <DatePicker {...this.props} />}
</Content>
Let me know if you wanted to do something else, I will update the answer.
EDIT:
Looking at your code in gist.github.com/fotoflo/13b9dcf2a078ff49abaf7dccd040e179, I figured what you are trying to do.
In short, you trying to show datepicker on click of a button. Unfortunately, this is not possible at the moment looking at Nativebase - how to show datepicker when clicking input? and the documentation https://docs.nativebase.io/Components.html#date-picker-def-headref.
If you really wanna have it, you should think about these possible solution,
Option 1: fork native-base do your manipulation and use the datepicker or even submit the PR to native-base for future use.
Option2: you can use any 3rd party library for eg: https://www.npmjs.com/package/react-native-modal-datetime-picker.
Or my favourite option 3:
import { TouchableOpacity, Text, Modal, View, Platform, DatePickerIOS, DatePickerAndroid } from 'react-native';
state = {
currentDate: date,
showiOSDatePicker: false,
chosenDate: date,
formattedDate
}
showDatePicker = async () => {
if (Platform.OS === 'ios') {
this.setState({
showiOSDatePicker: true
});
} else {
const { chosenDate, currentDate } = this.state;
try {
const {action, year, month, day} = await DatePickerAndroid.open({
date: chosenDate,
maxDate: currentDate
});
if (action !== DatePickerAndroid.dismissedAction) {
const dateSelected = new Date(year, month, day);
const formattedDate = this.getFormattedDate(dateSelected)
this.setState({chosenDate: dateSelected, formattedDate});
console.log(formattedDate)
}
} catch ({code, message}) {
console.warn('Cannot open date picker', message);
}
}
}
render() {
const { showiOSDatePicker } = this.state;
return (
<View>
{showiOSDatePicker &&
<Modal
animationType="fade"
transparent
visible={showiOSDatePicker}
onRequestClose={() => {
Alert.alert('Modal has been closed.');
}}>
<View
style={{
display: 'flex',
flex: 1,
justifyContent: 'center'
}}
>
<View style={{
margin: 22,
backgroundColor: 'rgba(240,240,240,1)'
}}>
<View
style={{
borderBottomColor: 'rgba(87,191,229,1)',
borderBottomWidth: 2,
display: 'flex',
justifyContent: 'center',
height: 70,
paddingRight: 20
}}
>
<Text style={{
color: 'rgba(40,176,226,1)',
fontSize: 20,
paddingLeft: 20
}}>
{formattedDate}
</Text>
</View>
<DatePickerIOS
date={chosenDate}
onDateChange={this.setDate}
maximumDate={currentDate}
mode="date"
/>
<TouchableOpacity
style={{
borderTopColor: 'rgba(220,220,220,1)',
borderTopWidth: 1,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: 50
}}
onPress={this.onCloseDatePicker}
>
<Text>
Done
</Text>
</TouchableOpacity>
</View>
</View>
</Modal>
}
<TouchableOpacity onPress={this.showDatePicker}>
<Text>Show Date</Text>
</TouchableOpacity>
</View>
);
}
Let me know if this make sense, or I will put together a working example in https://snack.expo.io/
Cheers
you have to give a ref to DatePicker
<Content>
<Button onPress={this.DatePicker.showDatePicker}>
<DatePicker ref={ref => this.DatePicker = ref } props}/>
</Content>
I had the same problem and this was my solution:
NativeBase DatePicker:
<DatePicker
defaultDate={new Date(2018, 4, 4)}
minimumDate={new Date(2018, 1, 1)}
maximumDate={new Date(2020, 12, 31)}
locale={"es"}
timeZoneOffsetInMinutes={undefined}
modalTransparent={true}
animationType={"fade"}
androidMode={"default"}
placeHolderText="Select date"
textStyle={{ color: "green" }}
placeHolderTextStyle={{ color: "#d3d3d3" }}
onDateChange={this.setDate.bind(this)}
disabled={false}
ref={c => this._datePicker = (c) }
/>
And with this you can open the datePicker:
<Button onPress={()=>{ this._datePicker.setState({modalVisible:true})}}>
<Text>
showDatePicker
</Text>
</Button>
I hope it helps

How to set the textinput box above the Keyboard while entering the input field in react native

I am using react-native TextInput component. Here I need to show the InputBox above the keyboard if the user clicks on the textInput field.
I have tried below but i am facing the issues
1. Keyboard avoiding view
a. Here it shows some empty space below the input box
b. Manually I need to scroll up the screen to see the input field which I was given in the text field
c. Input box section is hiding while placing the mouse inside the input box
2. react-native-Keyboard-aware-scroll-view
a.It shows some empty space below the input box
b.ScrollView is reset to the top of the page after I moving to the next input box
Here I set the Keyboard-aware-scroll-view inside the ScrollView component
Kindly clarify
My example code is
<SafeAreaView>
<KeyboardAvoidingView>
<ScrollView>
<Text>Name</Text>
<AutoTags
//required
suggestions={this.state.suggestedName}
handleAddition={this.handleAddition}
handleDelete={this.handleDelete}
multiline={true}
placeholder="TYPE IN"
blurOnSubmit={true}
style= {styles.style}
/>
</ScrollView>
</KeyboardAvoidingView>
</SafeAreaView>
[https://github.com/APSL/react-native-keyboard-aware-scroll-view]
Give your TextInput a position: absolute styling and change its position using the height returned by the keyboardDidShow and keyboardDidHide events.
Here is a modification of the Keyboard example from the React Native documentation for demonstration:
import React, { Component } from 'react';
import { Keyboard, TextInput } from 'react-native';
class Example extends Component {
state = {
keyboardOffset: 0,
};
componentDidMount() {
this.keyboardDidShowListener = Keyboard.addListener(
'keyboardDidShow',
this._keyboardDidShow,
);
this.keyboardDidHideListener = Keyboard.addListener(
'keyboardDidHide',
this._keyboardDidHide,
);
}
componentWillUnmount() {
this.keyboardDidShowListener.remove();
this.keyboardDidHideListener.remove();
}
_keyboardDidShow(event) {
this.setState({
keyboardOffset: event.endCoordinates.height,
})
}
_keyboardDidHide() {
this.setState({
keyboardOffset: 0,
})
}
render() {
return <View style={{flex: 1}}>
<TextInput
style={{
position: 'absolute',
width: '100%',
bottom: this.state.keyboardOffset,
}}
onSubmitEditing={Keyboard.dismiss}
/>
</View>;
}
}
First of all, You don't need any extra code for Android platform. Only keep your inputs inside a ScrollView. Just use KeyboardAvoidingView to encapsulate the ScrollView for iOS platform.
Create function such as below which holds all the inputs
renderInputs = () => {
return (<ScrollView
showsVerticalScrollIndicator={false}
style={{
flex: 1,
}}
contentContainerStyle={{
flexGrow: 1,
}}>
<Text>Enter Email</Text>
<TextInput
style={styles.text}
underlineColorAndroid="transparent"
/>
</ScrollView>)
}
Then render them inside the main view as below
{Platform.OS === 'android' ? (
this.renderInputs()
) : (
<KeyboardAvoidingView behavior="padding">
{this.renderInputs()}
</KeyboardAvoidingView>
)}
I have used this method and I can assure that it works.
If it is not working then there is a chance that you are missing something.
Hooks version:
const [keyboardOffset, setKeyboardOffset] = useState(0);
const onKeyboardShow = event => setKeyboardOffset(event.endCoordinates.height);
const onKeyboardHide = () => setKeyboardOffset(0);
const keyboardDidShowListener = useRef();
const keyboardDidHideListener = useRef();
useEffect(() => {
keyboardDidShowListener.current = Keyboard.addListener('keyboardWillShow', onKeyboardShow);
keyboardDidHideListener.current = Keyboard.addListener('keyboardWillHide', onKeyboardHide);
return () => {
keyboardDidShowListener.current.remove();
keyboardDidHideListener.current.remove();
};
}, []);
You can use a scrollview and put all components inside the scrollview and add automaticallyAdjustKeyboardInsets property to scrollview.it will solve your problem.
automaticallyAdjustKeyboardInsets Controls whether the ScrollView should automatically adjust its contentInset and
scrollViewInsets when the Keyboard changes its size. The default value is false.
<ScrollView automaticallyAdjustKeyboardInsets={true}>
{allChildComponentsHere}
<View style={{ height: 30 }} />//added some extra space to last element
</ScrollView>
Hope it helps.
you can use KeyboardAvoidingView as follows
if (Platform.OS === 'ios') {
return <KeyboardAvoidingView behavior="padding">
{this.renderChatInputSection()}
</KeyboardAvoidingView>
} else {
return this.renderChatInputSection()
}
Where this.renderChatInputSection() will return the view like textinput for typing message. Hope this will help you.
For android you can set android:windowSoftInputMode="adjustResize" for Activity in AndroidManifest file, thus when the keyboard shows, your screen will resize and if you put the TextInput at the bottom of your screen, it will be keep above keyboard
react-native-keyboard-aware-scroll-view caused similar issue in ios. That's when I came across react-native-keyboard-aware-view. Snippets are pretty much same.
<KeyboardAwareView animated={true}>
<View style={{flex: 1}}>
<ScrollView style={{flex: 1}}>
<Text style={{fontSize: 20, color: '#FFFFFF'}}>A</Text>
<Text style={{fontSize: 20, color: '#FFFFFF'}}>B</Text>
<Text style={{fontSize: 20, color: '#FFFFFF'}}>C</Text>
<Text style={{fontSize: 20, color: '#FFFFFF'}}>D</Text>
</ScrollView>
</View>
<TouchableOpacity style={{height: 50, backgroundColor: 'transparent', alignItems: 'center', justifyContent: 'center', alignSelf: 'stretch'}}>
<Text style={{fontSize: 20, color: '#FFFFFF'}}>Submit</Text>
</TouchableOpacity>
</KeyboardAwareView>
Hope it hepls
You will definitely find this useful from
Keyboard aware scroll view Android issue
I really don't know why you have to add
"androidStatusBar": {
"backgroundColor": "#000000"
}
for KeyboardawareScrollview to work
Note:don't forget to restart the project without the last step it might not work
enjoy!
I faced the same problem when I was working on my side project, and I solved it after tweaking KeyboardAvoidingView somewhat.
I published my solution to npm, please give it a try and give me a feedback! Demo on iOS
Example Snippet
import React from 'react';
import { StyleSheet, TextInput } from 'react-native';
import KeyboardStickyView from 'rn-keyboard-sticky-view';
const KeyboardInput = (props) => {
const [value, setValue] = React.useState('');
return (
<KeyboardStickyView style={styles.keyboardView}>
<TextInput
value={value}
onChangeText={setValue}
onSubmitEditing={() => alert(value)}
placeholder="Write something..."
style={styles.input}
/>
</KeyboardStickyView>
);
}
const styles = StyleSheet.create({
keyboardView: { ... },
input: { ... }
});
export default KeyboardInput;
I based my solution of #basbase solution.
My issue with his solution that it makes the TextInput jumps up without any regard for my overall view.
That wasn't what I wanted in my case, so I did as he suggested but with a small modification
Just give the parent View styling like this:
<View
style={{
flex: 1,
bottom: keyboardOffset,
}}>
And it would work! the only issue is that if the keyboard is open and you scrolled down you would see the extra blank padding at the end of the screen.
android:launchMode="singleTask"
android:windowSoftInputMode="stateAlwaysHidden|adjustPan"
write these two lines in your android/app/src/main/AndroidManifest.xml
in activity tag
flexGrow: 1 is the key.
Use it like below:
<ScrollView contentContainerStyle={styles.container}>
<TextInput
label="Note"
value={currentContact.note}
onChangeText={(text) => setAttribute("note", text)}
/>
</ScrollView>
const styles = StyleSheet.create({
container: {
flexGrow: 1,
},
});
Best and Easy Way is to use Scroll View , It will Automatically take content Up and TextInput will not be hide,Can refer Below Code
<ScrollView style={styles.container}>
<View>
<View style={styles.commonView}>
<Image source={firstNameIcon} style={{width: 25, height: 25}}></Image>
<Text style={styles.commonTxt}>First Name</Text>
</View>
<TextInput
onFocus={() => onFocus('firstName')}
placeholder="First Name"
style={styles.txtInput}
onChangeText={(text) => onChangeText(text, 'firstName')}
value={firstNameValue}
/>
</View>
<View>
<View style={styles.commonView}>
<Image source={LastNameIcon} style={{width: 25, height: 25}}></Image>
<Text style={styles.commonTxt}>Last Name</Text>
</View>
<TextInput
onFocus={() => onFocus('lastName')}
placeholder="Last Name"
style={styles.txtInput}
onChangeText={(text) => onChangeText(text, 'lastName')}
value={lastNameValue}
/>
</View>
<View>
<View style={styles.commonView}>
<Image source={callIcon} style={{width: 25, height: 25}}></Image>
<Text style={styles.commonTxt}>Number</Text>
</View>
<TextInput
onFocus={() => onFocus('number')}
placeholder="Number"
style={styles.txtInput}
onChangeText={(text) => onChangeText(text, 'number')}
value={numberValue}
/>
</View>
<View>
<View style={styles.commonView}>
<Image source={emailIcon} style={{width: 25, height: 25}}></Image>
<Text style={styles.commonTxt}>Email</Text>
</View>
<TextInput
onFocus={() => onFocus('email')}
placeholder="Email"
style={styles.txtInput}
onChangeText={(text) => onChangeText(text, 'email')}
value={emailValue}
/>
</View>
<View style={styles.viewSavebtn}>
<TouchableOpacity style={styles.btn}>
<Text style={styles.saveTxt}>Save</Text>
</TouchableOpacity>
</View>
</ScrollView>
go to your Android>app>src>main> AndroidManifest.xml
write these 2 lines :
android:launchMode="singleTop" android:windowSoftInputMode="adjustPan"

How to close swipe item in react-native?

I have this code (get from native-base example) that is working fine. But after click on either sides (right or left), the 'swipe' still open. I know that there is a method called closeRow(), but I don't know how to apply in this case.
Left button is for 'split' item into 2 or more, while right button is to delete current item. What I need is to close all opened rows in this list. Why all? Because in the case of 'delete' function, the current item is deleted in the right way, but the next-one get right button opened (since it's the same 'index' of list, even if the item itself is different).
This is my current code:
<Container style={styles.container}>
<Header>
<Left>
<Button transparent onPress={() => this.props.navigation.goBack()}>
<Icon name="arrow-back" />
</Button>
</Left>
<Body>
<Title>{translate("title", { ...i18n_opt, name })}</Title>
</Body>
</Header>
<Content>
<Modal
isVisible={this.state.visibleModal === true}
animationIn={"slideInLeft"}
animationOut={"slideOutRight"}
>
{this._renderModalContent()}
</Modal>
<View style={styles.line}>
<View style={{ flex: 2 }}>
<Text style={[styles.alignCen, styles.headerTitle]}>
{translate("lap", { ...i18n_opt })}
</Text>
</View>
<View style={{ flex: 10 }}>
<Text style={[styles.alignCen, styles.headerTitle]}>
{translate("time", { ...i18n_opt })}
</Text>
</View>
<View style={{ flex: 3 }}>
<Text
style={[
{ paddingRight: 10 },
styles.alignRig,
styles.headerTitle
]}
>
{translate("diff", { ...i18n_opt })}
</Text>
</View>
</View>
<List
enableEmptySections
dataSource={laps2}
ref={c => {
this.component = c;
}}
renderRow={data => <PersonalRankItem dados={data} />}
renderLeftHiddenRow={data => (
<Button
full
onPress={() => {
this.setState({
...this.state,
visibleModal: true,
cur_tx_id: tx_id,
cur_lap: data.lap
});
}}
style={{
backgroundColor: "#CCC",
flex: 1,
alignItems: "center",
justifyContent: "center",
marginBottom: 6
}}
>
<MaterialCommunityIcons
name="arrow-split-vertical"
size={20}
color="#5e69d9"
/>
</Button>
)}
renderRightHiddenRow={(data, secId, rowId, rowMap) => (
<Button
full
danger
onPress={_ => {
//alert("Delete");
//console.log("Data.lap:",data.lap);
dispatchDeleteLap(tx_id, data.lap, true);
}}
style={{
flex: 1,
alignItems: "center",
justifyContent: "center",
marginBottom: 6
}}
>
<Icon active name="trash" size={20} />
</Button>
)}
leftOpenValue={70}
rightOpenValue={-70}
/>
</Content>
</Container>
Goal
You need to close all the rows, each time one of row side button clicked. The next problem is when item deleted, the next row is opened even the content is different.
How?
All you need is first, collect the ref of each rows and then when the button clicked, trigger the closeRow method of all ref's row. And the important part, make your row key persistent and unique to avoid problem like in your case.
Quick Code Sample
class Screen extends Component {
constructor(props) {
super(props);
this._rowRefs = [];
}
// this is used to collect row ref
collectRowRefs = (ref) => {
this._rowRefs.push(ref);
};
// your render row function
renderRow = (data) => (
// make this row key consistent and unique like Id, do not use index counter as key
<PersonalRankItem key={data.id} dados={data} ref={this.collectRowRefs}/>
);
// When your hidden side button is clicked
onButtonClicked = (data) => {
// do the button normal action
// ....
// close each row
this._rowRefs.forEach((ref) => {
ref.closeRow();
});
};
// this is your hidden side button
renderLeftHiddenRow = () => (
<Button onClick={this.onButtonClicked} />
);
render() {
// Your List in here
return (
<List
renderRow={this.renderRow}
renderLeftHiddenRow={this.renderLeftHiddenRow}
/>
)
}
}

FlatListFooter can't be displayed

I want to add footer to my flatList :
i try this code :
renderFooter = () => {
return (
<View
style={{
paddingVertical: 20,
borderTopWidth: 1,
borderColor: "#CED0CE"
}}
>
<Button> This is footer </Button>
</View>
);
}
<FlatList
data={menuData}
renderItem={({item}) => <DrawerItem navigation={this.props.navigation} screenName={item.screenName} icon={item.icon} name={item.name} key={item.key} />}
ListFooterComponent ={this.renderFooter}
/>
But no footer appears when running.
Any help please
You used the component
ListFooterComponent
in right way. you need to check your render method for footer. I faced the same issue and i follow this example, and it helps me. I hope it will help you.
Simple way/hack. In the menuData array, you just add a flag (i called) to the child object to indicate that it's a last item. For eg:
If you can modify your menuData structure, added lastItem prop true to indicate that it's the last item :
const menuData = [
{name:'menu1', screenName:'screen1', icon:'../assets/icon1.png'},
{name:'menu2', screenName:'screen2', icon:'../assets/icon2.png', lastItem:true}
];
and then
renderFlatItems = ({item}) => {
const itemView = null;
if (!items.lastItem) {
itemView = <DrawerItem navigation={this.props.navigation} screenName={item.screenName} icon={item.icon} name={item.name} key={item.key} />
} else {
itemView = <View style={{padding:100}}><Button> This is footer </Button> </View>
}
return {itemView};
}
then use it in the Flatlist like so
<FlatList
data={menuData}
renderItem={this.renderFlatItems}
/>
If you want a footer that remains at the bottom of the screen "Above" the list, then you can just add a View after the FlatList.
<View>
<FlatList style={{flex: 1}} />
<View
style={{
position: 'absolute',
left: 0,
right: 0,
bottom: 0,
height: 50,
}}
/>
</View>