Inconsistent width of separator while displaying list items - react-native

Following is the code to display list items with separators
</View>
<Text style={{padding: 10}}>List Item</Text>
<View style={{height: StyleSheet.hairlineWidth, backgroundColor: 'grey'}} />
</View>
(Kindly assume that I have repeated above piece of code multiple times to get the list view appearence)
there is some inconsistency in separators
this issue had already been posted in stack overflow and in github, but there hasn't been any permanent fix for this issue and it's been almost 2 years since these issue has been posted.
So, I just want to know that has anybody found permanent fix for this in recent times.

One solution I found that works usually well enough is to add a small margin to the divider.
const styles = StyleSheet.create({
divider: {
borderBottomColor: '#ccc',
borderBottomWidth: StyleSheet.hairlineWidth,
marginVertical: 1,
},
});
return <View style={styles.divider} />

As far as I know this is an issue related to emulators and IOS simulator because of scaling. This is just a visual mispresentation. I don't think it would happen on a real device.
Try your code with a real device or if its possible try with no scaling with device emulators or simulators.

I found that this is a bug in React-Native for Android where React-Native renders a separator for the bottom of one FlatList item, and then a second separator for the top of the next FlatList item, when the FlatList should really only render one separator between each FlatList item. I figured this out when I added marginVertical: 1 to my ItemSeparatorComponent and noticed the two distinct separators in between each FlatList item. The fix I found was to set my ItemSeparatorComponent height to 2 pixels, and then set marginVertical to -1 pixel:
<FlatList
data={companyGrowthRankings}
renderItem={renderItem}
keyExtractor={item => `${Math.random()}`}
ItemSeparatorComponent={() => <View style={{ width: windowWidth, height: 2, marginVertical: -1, backgroundColor: lessBlack }}></View>}
/>

Related

ReactNative - Text being cut off in repeating list of results on customer's android phone

I am noticing the following code in ReactNative (React 0.59), which represents a single search result item, is sometimes cutting off the last line of text on a client's android phone (but not on any of my android phones or simulators)
<View style={this.props.style}>
<View style={{ flexDirection: 'row' }}>
<Text style={styles.textStyle}>
{this.itemSentences()}
</Text>
</View>
<View style={{justifyContent: 'center', alignItems: 'center', flex: 1, marginTop: -7}}>
<Text style={{color: '#000', fontSize: ellipsisFontSize, fontWeight: '600'}}>{ellipsisText}</Text>
</View>
</View>
In the image below, you can see the effect, which is an incomplete sentence being rendered:
It almost looks like there isn't enough room to render the rest of the text, so it cuts it off. Again, on my phone, it renders the whole paragraph but in the client's screen shot, it is cut off.
Any initial suggestions or things I can do? I tried reducing the font, increasing the font, changing padding, but no luck. What other details can I provide? Thank you!
Edit:
Here is the container the above list items appear in:
<View style={styles.containerStyle}>
<FlatList
onContentSizeChange={ (x, y) => { this.layoutChanged(x, y) } }
onLayout={(event) => this.layoutChanged(event)}
keyboardShouldPersistTaps="always"
keyExtractor={(item, index) => index.toString()}
data={dataSource}
ListFooterComponent={footer}
ListHeaderComponent={header}
scrollEventThrottle={16}
onScroll={this.handleScroll.bind(this)}
language={this.props.language}
renderItem={this.renderItem.bind(this)}
/>
<AnimatedEditedResults
style={[editResultsStyle, {transform: [{translateX: this.state.editResultsOverlayX}]}]}
editResultsXButtonPressed={this.hideEditResultsOverlay.bind(this)}
applyFilterPressed={this.applyFilterPressed.bind(this)}
searchResults={this.props.originalSearchResults.Results}
selectedSources={this.props.selectedSources}
sentenceNumber={this.props.sentenceNumber}
hasMadeChanges={this.props.hasMadeChanges}
clearFilterPressed={this.props.clearFilterPressed}
language={this.props.language}
/>
</View>
Any reason why you cant wrap the component in a ScrollView
After playing with over 100+ different kinds of builds, different attempts, etc. I finally found the issue.
There is a property on called "TextBreakStyle" and by default it is "complex". By changing to "Simple", the issue went away. This apparently only plagues certain types of phones/devices.
Hope this helps someone!

RecyclerListView Error in React Native APP

This is my code:
<RecyclerListView
layoutProvider={this._layoutProvider}
dataProvider={this.state.dataProvider}
rowRenderer={this._rowRenderer}
></RecyclerListView>
And I get the error:
LayoutException: RecyclerListView needs to have a bounded size.
Currently height or, width is 0.Consider adding style={{flex:1}} or,
fixed dimensions
According to a few issues from Github it solves easy (wrap it and set minHeight/minWidth = 1 in a wrapper).
<View style={{ minHeight: 1, minWidth: 1 }}>
<RecyclerListView ... />
</View>
PS: For my case (vertical list) I added 'minHeight: 1' only.
Wrap your recyclerlistview in a view
You can give height to the view or you can give height to the style under recyclerlistview. Example:
<View style={{
marginTop:5,
marginBottom:5,
backgroundColor:"#f3f3f3",
height:"100%"}> //Here
<RecyclerListView
dataProvider={this.state.dataProvider}
layoutProvider={this.layoutProvider}
rowRenderer={this.rowRenderer}
style={{height:"100%",}} //or Here, If you add here then the last row of your rendered data list will not have any issue and may fulfill your all issues
onEndReached={this.fetchMore}
onEndReachedThreshold={0.5}
renderFooter={()=>{
<Text style={{padding:10, fontWeight:"bold", textAlign:"center"}}>
Loading... </Text>
}}

Listview has been removed from react native error after adding react-native-gridview

I have installed react-native-gridview and after that I am getting this error.
The line number shown in error is Media.js:134. It contains the following code.
<GridView data={this.state.dataList} itemsPerRow={2}
renderItem={(item) => {
return (
<View style={{ flex: 1, backgroundColor: '#8F8', borderWidth: 1, margin: 8 }}>
<Image style={styles.imageThumbnail} source={{ uri: item.path}} />
</View>
);
}}/>
I can't understand why I am getting this error. I am not using any ListView
Please Help. Thanks.
The problem is that react-native-gridview is using Listview in their library as you can see here.
And now react-native stopped giving support to Listviews, rather now you
can use FlatList, SectionList and modify them as per your requirement, as they have more features and stability.
That's why you are getting the above error.

Include ListHeaderComponent in numColumns - React-Native

Does anyone know how I can include the header of a flatlist in the columns?
For example, in the image below I would like "Design" to follow "New +" in the same row.
Example Screenshot
Here is my code in render:
<FlatList
data={goalItems}
extraData={this.props}
renderItem={this._renderGoal}
ListHeaderComponent={this._renderGoalHeader}
keyExtractor={item => item.goal_id}
showsVerticalScrollIndicator={false}
numColumns={2}
/>
and in _renderGoal:
_renderGoal = ({ item }) => (
<TouchableOpacity
onPress={() => this.openOptions(item)}
style={{ padding: 10 }}>
<Bubble>
<Text style={[styles.normalText]}>{item.name}</Text>
<View style={{ alignItems: 'center' }}>
<Text>{formatSeconds(item.total_time)}</Text>
</View>
</Bubble>
</TouchableOpacity>
);
and in _renderGoalHeader:
_renderGoalHeader = () => (
<TouchableOpacity
onPress={() => this.openAddGoal()}
style={{ padding: 10 }}>
<Bubble style={[styles.newGoal]}>
<Text style={[styles.touchableText]}>New +</Text>
</Bubble>
</TouchableOpacity>
)
Thanks in advance.
As a temporary fix, I removed numColums from the flatList and added the following:
contentContainerStyle={{ flexWrap: 'wrap', flexDirection: 'row', width: 345 }}
I would love to be proven wrong here, but as far as I can tell, this cannot be done using numColumns. There is a workaround which I'll list at the end, but first the reasoning:
Explanation
I ran into this same issue but with the footer and did a code dive into the React Native source to see what was happening. First thing I did was use the inspector and I noticed that the header and footer of a FlatList are wrapped in a View while each row of columns is wrapped in CellRenderer > View. This is the first clue that FlatList does not account for headers and footers in numColumns. This is problematic because FlatList does not support masonry type layouts. This hints at the fact that there are many assumptions being made about how they are handling rendering the rows - that is, items are separated into rows to be rendered.
With these clues, I went into the source and found that FlatList passes its own custom renderItem down to VirtualizedList. Meanwhile, ListHeaderComponent and ListFooterComponent are passed down as is. They are never used in FlatList. Not a good sign as you'll see that the aforementioned _renderItem is what handles grouping the items together into columns to render using flexDirection: 'row' and whatever is passed down with columnWrapperStyle.
But perhaps VirtualizedList is smart enough to combine the header and footer into data that gets passed into renderItem?
Sadly, this is not the case. If you follow the code in VirtualizedList, you'll eventually see all the logic get played out in render() where:
a cells array is created
that first has the header pushed into it
followed by all of the data pushed into it via its _pushCells helper method
This is where CellRenderer appears;
hence why headers and footers are not wrapped by this whereas the rows are.
This is also where FlatLists _renderItem is used explaining why you get numColumns number of items wrapped in a CellRenderer.
and then finished with the footer being pushed in the same manner as the header.
This cells array of React components is then eventually cloned which helps with things such as keeping scroll position.
And finally rendered.
Do to this implementation, you will always get a fixed CellRenderer component which prevents headers and footers from being included as part of numColumns.
Workaround (not recommended)
If you've used React Native prior to FlatList being released, you'll know that one old workaround was to be very careful with your dimensions and use flexWrap: 'wrap'. It's actually documented within the source code as it will spit out a warning if you use this method of handling columns. Do note that it is NOT recommended to do this (I believe performance and perhaps scroll position may be some of the reasons against using this method).
If you are willing to do this though, add these styles to your contentContainerStyle:
flexDirection: 'row',
flexWrap: 'wrap',
// You'll probably also want this for handling empty cells at the end:
justifyContent: 'flex-start',
and remove the numColumns prop. Then make sure to manually size your component dimensions to get the correct looking column style layout you desire. This should allow your header and footer to render as part of the columns.
If you want to do it with numOfColumns, than use flexDirection:'row' within your header component
_renderGoalHeader = () => (
return(
<View style={{flexDirection:'row'}}>
<TouchableOpacity
onPress={() => this.openAddGoal()}
style={{ flex:1, padding: 10, }}>
<Bubble style={[styles.newGoal]}>
<Text style={[styles.touchableText]}>New +</Text>
</Bubble>
</TouchableOpacity>
<View>
<View style={{flex:1}}/> //this view is just to cover half width
);
)

Flexbox align images with different size to fill the area

I am using React Native's flexbox (not css flexbox). I am creating an image gallery and the first image has to be double the size, and the rest of the images smaller. Works good, but I have a problem that the third image is displayed in new row, instead where the blank space is.
Is it possible to achieve such behaviour with flex-box, so that the third image would be below the first small image?
I tried all combinations with aligning items, self aligning, flex directions, but no success. If needed I can provide a small example of the code which I already have.
I don't have a fully responsive answer, but this may be helpful here:
<View style={{ flexDirection: 'column' }}>
<View style={{ flexDirection: 'row' }}>
{this.renderPhoto(0)}
<View>
{this.renderPhoto(1)}
{this.renderPhoto(2)}
</View>
</View>
<View style={{ flexDirection: 'row' }}>
{render rest...}
</View>
</View>
Try this component. Maybe it will help you
https://xudafeng.github.io/autoresponsive-react/