React native flatlist leaves empty spaces, for items that don't match conditions - react-native

The first row shows a single card, this is because the item suppose to be there doesn't match the condition stated. But I want to remove this space, and put the next card which is currently on the next line there.
{state.data ? <FlatList
data={state.data}
renderItem={({ item }) => {
console.log(item)
return (
<View style={{ justifyContent: 'space-evenly', marginHorizontal: 0 }}>
<View>
{item.available == 1 ?
<TouchableOpacity activeOpacity={.8} onPress={() => navigation.navigate('Appointment', { id: item.id, name: item.name, phone: item.phone, email: item.email, session: item.session, player_id: item.player_id, picture: item.picture })} >
<Card style={{ width: width / 2.05, alignItems: 'center', justifyContent: 'center', borderRadius: 15, paddingTop: 10, height: height / 2.4 }}>
<CardItem cardBody>
<Image
source={{ uri: 'http://example.com/storage/' + item.picture }}
style={{ height: 200, width: null, flex: 1 }}
/>
</CardItem>
<CardItem>
<Text> {item.name} </Text>
</CardItem>
</Card>
</TouchableOpacity>
: null}
</View>
</View>
)
}}
numColumns={2}
/> : <ActivityIndicator size="large" style={{ alignItems: 'center', justifyContent: 'center', flex: 1, flexDirection: 'row' }} />}
The null value just shows that empty space, is there a way to completely remove this empty space?

You need to filter your data. Otherwise, your code will create empty Views.
Try to filter your data as follows.
It would be good if you move this filter logic from your render method.
{state.data ? <FlatList
data={state.data.filter(item => item && item.available === 1)}
renderItem={({ item }) => {
return (
<View style={{ justifyContent: 'space-evenly', marginHorizontal: 0 }}>
<TouchableOpacity activeOpacity={.8}
onPress={() => navigation.navigate('Appointment', { id: item.id, name: item.name, phone: item.phone, email: item.email, session: item.session, player_id: item.player_id, picture: item.picture })} >
<Card style={{ width: width / 2.05, alignItems: 'center', justifyContent: 'center', borderRadius: 15, paddingTop: 10, height: height / 2.4 }}>
<CardItem cardBody>
<Image
source={{ uri: 'http://example.com/storage/' + item.picture }}
style={{ height: 200, width: null, flex: 1 }}
/>
</CardItem>
<CardItem>
<Text> {item.name} </Text>
</CardItem>
</Card>
</TouchableOpacity>
</View>
)
}}
numColumns={2}
/> : <ActivityIndicator size="large" style={{ alignItems: 'center', justifyContent: 'center', flex: 1, flexDirection: 'row' }} />}

Related

Ref in flatlist items does not return correct PageY position when loading more data in a list

I am trying to display dropdown below flatlist items. Pagination is implemented in Flatlist, so when i load data for first-page, the dropdown position is calculated accurately. but when i load data for another pages, pageY postion in ref measure method is increased by list size. So due to this dropdown isn't displayed in visible area. I am attaching my code for reference.
this is my render method.
render() {
let { list, } = this.props;
const {top,listVisibity,articleDropdown} = this.state;
return (
<View style={{flex:1}}>
<OptimizedFlatList
maxToRenderPerBatch={10}
windowSize={16}
onEndReached={() => this.onEndReached()}
nestedScrollEnabled={false}
onScrollBeginDrag = {() => this.setState({listVisibity:false})}
onEndReachedThreshold={Platform.OS === 'ios' ? 0 : 0.01}
onMomentumScrollBegin={() => { this.onEndReachedCalledDuringMomentum = false; }}
data={list}
renderItem={({ item }) => this._renderItem(item)}
keyExtractor={item => item.id}
style={{ flexGrow: 1}}
ListFooterComponent={this.footer}
/>
</view>
}
And here is list and sublist rendering
_renderItem = item => {
return (
<View style={styles.container}>
<ShadowView style={styles.shadowStyle}>
<View style={styles.listItem} >
<View style={{ flex: 0.6, flexDirection: 'row' }}>
<Image
source={constants.images.dot}
style={{ alignSelf: 'center', width: RFValue(12), resizeMode: 'contain', marginRight: 10 }}
/>
<Highlighter
highlightStyle={{backgroundColor: 'yellow'}}
searchWords={[this.props.searchedText]}
textToHighlight= {item.name.toUpperCase()+" ("+item.topics.length+")"}
style={{ color: "#0C3C7F", alignSelf: 'center', fontWeight: '500', fontFamily:constants.fontFamily.SFProDisplay }}
/>
</View>
<View style={{ flex: 0.4}}>
<TouchableOpacity onPress={() => {
this.updateSelection(item)
}}>
{item.isExpanded ? <Image
source={constants.images.dropdownArrow}
style={{ alignSelf: 'flex-end', resizeMode: 'contain' }}
/> :
<Image
source={constants.images.arrowUp}
style={{ alignSelf: 'flex-end', resizeMode: 'contain' }}
/>
}
</TouchableOpacity>
</View>
</View>
</ShadowView>
{this.renderSubList(item)}
</View>
);
}
renderSubList = (item) => {
return <Collapsible collapsed={!item.isExpanded}>
<FlatList
data={item.topics}
scrollEnabled={false}
renderItem={({ item }) => (
<ShadowView style={item.isSelected? styles.topicShadowStyle_1:styles.topicShadowStyle}>
<View ref={ref => this.parentView = ref}
onLayout={(event) => {
this.find_dimesions(event.nativeEvent.layout) }}
style={[{flexDirection: 'row'}, item.isSelected ? { borderColor: constants.colors.lightBlue, borderTopLeftRadius: 10,borderBottomLeftRadius: 10,borderRadius:8, borderWidth: 2 } : {}]}>
{(item.fullTextUrl!=null && item.fullTextUrl!='') || (item.pdfLink!=null && item.pdfLink!='') ?
<View style={{ width: width * 4 / 100, backgroundColor: constants.colors.lightBlue, borderTopLeftRadius: 8, borderBottomLeftRadius: 8 }}></View>:
<View style={{ width: width * 4 / 100, backgroundColor: constants.colors.lightGray_1, borderTopLeftRadius: 8, borderBottomLeftRadius: 8 }}></View>
}
<View style={{ width: '95%' }}>
<TouchableWithoutFeedback onLongPress={() => this.props.updateShowSelectedIcon(item)} onPress={() => this.props.showDetails(item)}>
<View style={{ flexDirection: 'row', width: '100%' }}>
<View style={{ flex: 1, marginHorizontal: width * 3 / 100, marginVertical: height * 1.5 / 100, backgroundColor: constants.colors.white }}>
<View style={{ flexDirection: 'row', width: '100%' }}>
<View style={{ alignContent: 'flex-start', width: '65%' }}>
<Highlighter
highlightStyle={{backgroundColor: 'yellow'}}
searchWords={[this.props.searchedText]}
textToHighlight= {item.journal.toUpperCase()}
style={styles.jurnalTitle}
numberOfLines={2}
/>
</View>
<View style={{ alignContent: 'flex-end', width: '35%', }}>
<Text style={styles.dateStyle} >{item.date}</Text>
</View>
</View>
<View style={{ flexDirection: 'row', width: '100%', marginTop: height * 1 / 100 }}>
<View style={{ alignItems: 'flex-start', width: '70%' }}>
<Highlighter
highlightStyle={{backgroundColor: 'yellow'}}
searchWords={[this.props.searchedText]}
textToHighlight= {item.article}
style={{ fontWeight: 'bold', color: constants.colors.black_1, alignContent: 'flex-start' }}
numberOfLines={2}
/>
</View>
{!this.props.showSelectedIcon?
<View
ref={(ref) => { this.rowRefs[item.id] = ref; }}
// ref={ref => this[`myView${item.id}`]=ref}
onLayout={(event) => {
const {x, y, width, height} =event.nativeEvent.layout
}}
style={{position:'relative', alignItems: 'flex-end', width: '30%' }}>
<TouchableOpacity style={{ height: RFValue(20), width: RFValue(20) }}
onPress={() => this.calculateIconPosition(item)}>
{(item.fullTextUrl!=null && item.fullTextUrl!='') || (item.pdfLink!=null && item.pdfLink!='') ?
<Image
source={constants.images.Oval}
style={{ height: RFValue(20), width: RFValue(20) }}
/>:
<Image
source={constants.images.dropdown}
style={{ height: RFValue(20), width: RFValue(20) }}
/>
}
</TouchableOpacity>
{/* { <View onLayout={(event) => {
const {x, y, width, height} =event.nativeEvent.layout
console.log(y)
}} > </View>} */}
</View>:
<View
style={{ alignItems: 'flex-end', width: '30%' }}>
{item.isSelected?
<Image
source={constants.images.selected}
style={{ height: RFValue(20), width: RFValue(20) }}
/>:
<Image
source={constants.images.unselect}
style={{ height: RFValue(20), width: RFValue(20) }}
/>
}
</View>
}
</View>
</View>
</View>
</TouchableWithoutFeedback>
{this.renderNotesView(item)}
</View>
</View>
</ShadowView>
)}
keyExtractor={item => item.id}
/>
</Collapsible>
}
Item Measurement Method Call
calculateIconPosition = (item) => {
this.rowRefs[item.id].measure( (fx, fy, width, height, px, py) => {
console.log("=================PY=====================")
console.log(py)
})
}
Is there any way to get exact pageY position in flat list.

FlatList not visible even if i added it in React Native

I have added searchview then another row below that and then i have added flatlist in my view below the horizontal listview and i want to show it in full remaining height but it is not showing, there is also not any error in the code and also it doesn't show any error in console, here is a code :
<View style={styles.mainContainer}>
<View style={styles.searchView}>
<TextInput
style={styles.searchInput}
onChangeText={text => this.SearchFilterFunction(text)}
value={this.state.searchText}
underlineColorAndroid="transparent"
placeholder="Search Services"
placeholderTextColor={theme.colors.app_blue_light}
/>
<Image source={Images.search} style={styles.searchImage} />
</View>
{/* MapView */}
<View style={styles.MapToggleContainer}>
<Text style={styles.titleShop}>Select your shop</Text>
<Text style={styles.titleToggle}
onPress={this.toggleView}>List View</Text>
</View>
<View style={styles.shopListView}>
<FlatList
horizontal
style={styles.shopsList}
data={this.state.data}
renderItem={({ item: rowData }) => {
return (
<View style={styles.shopListItem}>
<Image source={require('./logo.png')} style={styles.shopImage} />
</View>
);
}}
keyExtractor={(item, index) => index}
/>
</View>
<MapboxGL.MapView>
<MapboxGL.Camera centerCoordinate={this.state.coordinates[0]} zoomLevel={14} />
<MapboxGL.MarkerView id='marker1' coordinate={this.state.coordinates[0]}>
<ImageBackground source={require('./chat.png')}
style={{ borderColor: 'black', borderWidth: 0, width: 80, height: 80, alignContent: 'center' }}>
<TouchableOpacity style={{ width: '100%', height: '100%', alignItems: 'center', justifyContent: 'center' }}
onPress={() => {
this.setState({ toolTipVisible: true })
}}>
<Tooltip
animated
isVisible={this.state.toolTipVisible}
content={<View style={{ width: '100%', height: '100%', backgroundColor: 'white' }}>
<View style={{ flexDirection: 'row' }}>
<Image source={require('./chat.png')} />
<View style={{ flexDirection: 'column' }}>
<Text style={{ marginHorizontal: 10, marginTop: 10 }}>123, Main st,</Text>
<Text style={{ marginHorizontal: 10, marginBottom: 10 }}>Chicago, IL 6061</Text>
</View>
</View>
<TouchableOpacity
style={{ backgroundColor: 'orange', margin: 10, alignItems: 'center' }}
onPress={() => { }}
>
<Text style={{ margin: 10, color: 'white' }}>Select Shop</Text>
</TouchableOpacity>
</View>}
placement="top"
onClose={() => this.setState({ toolTipVisible: false })} >
<Text style={{ color: 'white', fontWeight: 'bold', fontSize: 20 }} >$50.00</Text>
</Tooltip>
</TouchableOpacity>
</ImageBackground>
</MapboxGL.MarkerView>
</MapboxGL.MapView>
</View>
Styles
mainContainer: {
flex: 1,
backgroundColor: theme.colors.white
},
toggleContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
marginTop: '20#ms',
marginBottom:'10#ms',
marginHorizontal: '15#ms',
},
titleShop: {
fontFamily: 'Muli-Bold',
fontSize: '16#ms',
color: theme.colors.gray4
},
titleToggle: {
fontFamily: 'Muli-Bold',
fontSize: '11#ms',
color: theme.colors.gray4,
textDecorationLine: 'underline',
alignSelf:'center'
},
MapToggleContainer:{
flexDirection: 'row',
justifyContent: 'space-between',
marginTop: '10#ms',
marginBottom:'15#ms',
marginHorizontal: '15#ms',
},
shopListView:{
height:'60#ms'
},
shopsList:{
marginLeft:'5#ms',
marginRight:'15#ms',
},
shopListItem:{
elevation:5,
backgroundColor:'white',
marginLeft:'10#ms',
height:'50#ms',
width:'50#ms',
alignItems:'center',
justifyContent:'center',
borderRadius:'5#ms'
},
shopImage:{
width:'30#ms',
height:'30#ms',
},
And here is a result, as you can see the mapview below list is not visible
give height and width style to MapboxGL.MapView
<MapboxGL.MapView style={{width:Dimensions.get("window").width,height:400}}>

React-Native how to use KeyboardAvoidingView

Both the header and the chat container move-up when I start typing some message.
I have tried to use KeyboardAvoidingView inside my view container, however, it did not work, I'm not sure if the KeyboardAvoidingView is the best solution to control the keyboard inside the view and not familiar with it.
Below is my code:
render() {
const { myName, user, nome, message } = this.props;
return (
<View style={STYLES.main}>
<Animatable.View
style={STYLES.container}
animation={FADEIN}
easing='ease-in'
duration={1000}
>
<RenderHeader3 press={() => Actions.detalhes()} hcolor={'#298CFF'} color={'#FFF'} text={nome} icon={null} isize={null} />
<ScrollView contentContainerStyle={{ paddingHorizontal: 10, paddingTop: 5 }}>
<KeyboardAvoidingView
style={{ flex: 1 }}
behavior={null}
keyboardVerticalOffset={60}
>
<ListView
enableEmptySections
dataSource={this.dataSource}
renderRow={this.renderRow}
/>
</KeyboardAvoidingView>
</ScrollView>
<View style={{ flexDirection: 'row', backgroundColor: '#1A1C27', padding: 10 }}>
<View style={{ flex: 4 }}>
<TextInput
style={[STYLES.titleTxt, { color: '#000', backgroundColor: '#FFF', borderRadius: 40, paddingLeft: 13, paddingRight: 10 }]}
multiline
value={message}
onChangeText={(texto) => this.props.modificaMensagem(texto)}
/>
</View>
<View style={{ justifyContent: 'center', alignItems: 'center', paddingLeft: 10 }}>
<TouchableOpacity
style={{
height: 40,
width: 40,
borderRadius: 40,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#298CFF',
paddingRight: 2
}}
activeOpacity={0.5}
onPress={() => this.props.createChat(myName, user, nome, message)}
>
<CustomIcon
name='paper-plane'
size={25}
color='#FFF'
/>
</TouchableOpacity>
</View>
</View>
</Animatable.View>
</View>
);
}
}
make this changes
<KeyboardAvoidingView
style={{ flex: 1 }}
behavior="height"
keyboardVerticalOffset={60}
>
source
KeyboardAvoidingView has 3 types of behavior enum('height','position','padding') but you set it to null in your code.
Secondly you have not added KeyboardAvoidingView in with TextInput component
<KeyboardAvoidingView
style={{ flex: 1 }}
behavior={'height'}
keyboardVerticalOffset={60}
>

Im trying to render an object in a row but one of my images doesn't play nice with the others using flexDirection:row

Im trying to make this view with a bubble image in the margin between the left of the screen and the larger square images like the picture below
but my bubble will not stay in line with the view and
I get this
`
const Recipe = ({ name, durationLabel, numberOfServings, handlePress, handlePush }) => (
<View styles={{flexDirection: 'row'}}>
<TouchableHighlight onPress={handlePush}>
<View syle={{ justifyContent:'center'}}>
<Image
source={require("app/assets/icons/bubbleOff.png")}
style={{justifyContent:'center'}}
/>
</View>
</TouchableHighlight>
<TouchableHighlight onPress={handlePress}>
<View style={styles.recipeTile}>
<Image
source={require("app/assets/cheesecake.png")}
style={styles.recipeImage}
/>
<View style={styles.recipeInfo}>
<View style={styles.recipeNameRow}>
<Text style={styles.recipeName}>{name}</Text>
<Image
style={{ marginRight: 10 }}
source={require("app/assets/icons/heart.png")}
/>
</View>
<View style={styles.recipeStatsRow}>
<Text style={styles.recipeStats}>
{durationLabel}
{' '}
| Serves
{' '}
{numberOfServings}
</Text>
</View>
</View>
</View>
</TouchableHighlight>
</View>
);`
my styles
`
recipeTile: {
flexDirection: "row",
flex: 1,
margin: 10,
backgroundColor: "white",
marginLeft:60,
},
recipeImage: {
width: 100,
height: 100
},`
Use justifyContent: 'center' and alignItems: 'center' to align the image center.
const Recipe = ({
name,
durationLabel,
numberOfServings,
handlePress,
handlePush,
}) => (
<TouchableHighlight onPress={handlePush}>
<View style={{ flexDirection: 'row' }}>
<View style={{ flex: 0, justifyContent: 'center', alignItems: 'center', marginLeft: 5, marginRight: 5 }}>
<Image
source={require('assets/bubbleOff.png')}
style={{ height: 20, width: 20 }}
/>
</View>
<View style={{ flexDirection: 'row', flex: 1, backgroundColor: '#FFF' }}>
<View style={{ flex: 0 }}>
<Image
source={require('assets/cheesecake.png')}
style={styles.recipeImage}
/>
</View>
<View style={{ flex: 1 }}>
<Text style={styles.recipeName}>{name}</Text>
<Text style={styles.recipeStats}>
{durationLabel} | Serves {numberOfServings}
</Text>
</View>
<Image
style={{
marginRight: 10,
height: 20,
width: 20,
position: 'absolute',
right: -20,
top: 30,
}}
source={require('assets/heart.png')}
/>
</View>
</View>
</TouchableHighlight>
);
Working demo

Place a component to middle right in React Native

I am still learning about react native especially flexbox. So I have a TouchableOpacity that have some child components on it, like this:
And the problem is I can't move that arrow icon to the middle right of TouchableOpacity. I try with
justifyContent: 'center', alignItems: 'flex-end' But nothing happened. Here is my code :
<TouchableOpacity onPress={this.onRowPress}>
<View style={{ padding: 5 }}>
<CardSection style={{ flex: 1 }}>
<Icons name="monitor" size={50} style={{ paddingLeft: 10 }} />
<View style={{ flexDirection: 'column' }}>
<Text style={styles.channelStyle}>
{item.nama}
</Text>
<Text
style={
[item.status === 'Online' ? onlineTextStyle : offlineTextStyle]
}
>
{item.status}
</Text>
</View>
<Icons name="arrow-right" size={50} style={styles.arrowIconStyle} />
</CardSection>
</View>
</TouchableOpacity>
And this is the style:
const styles = {
channelStyle: {
fontSize: 25,
paddingLeft: 30
},
onlineTextStyle: {
paddingLeft: 30,
color: 'green'
},
offlineTextStyle: {
paddingLeft: 30,
color: 'red'
},
footerTextStyle: {
flex: 1,
textAlign: 'center',
color: '#fff',
padding: 5,
fontSize: 18
},
arrowIconStyle: {
justifyContent: 'center',
alignItems: 'flex-end'
}
};
Is there something I missed?
Could you try the following and let me know how it goes?
// 1. Add flexDirection row here.
<CardSection style={{ flex: 1, flexDirection: 'row' }}>
...code...
// 2. Add alignSelf here.
<Icons name="arrow-right" size={50} style={[styles.arrowIconStyle, {alignSelf: 'flex-end'}]} />
</CardSection>
If that doesn't work, try not doing the previous step 2 and instead try this.
...code...
<Icons name="arrow-right" size={50} style={styles.arrowIconStyle} />
const styles = {
...code...
arrowIconStyle: {
justifyContent: 'center',
alignSelf: 'flex-end'
}
};
Update
<TouchableOpacity onPress={this.onRowPress}>
<View style={{ padding: 5 }}>
<CardSection style={{flex: 1, flexDirection: 'row', justifyContent: 'space-between'}}>
<View style={{ flex: 1 }}>
<Icons name="monitor" size={50} style={{ paddingLeft: 10 }} />
<View style={{ flexDirection: 'column' }}>
<Text style={styles.channelStyle}>
{item.nama}
</Text>
<Text
style={[item.status === 'Online' ? onlineTextStyle : offlineTextStyle]}>
{item.status}
</Text>
</View>
</View>
<Icons name="arrow-right" size={50} style={styles.arrowIconStyle} />
</CardSection>
</View>
</TouchableOpacity>