Is there a way for keeping the title aligned, when adding a subtitle, in React Native Elements? - react-native

I'm using React Native Elements (1.0) to display my <ListItem />s. I was wondering if there is a way for keeping the title on the same line it was when adding a subtitle?
Here is what I currently have, which is wrong:
What I would like to have is the "1x" to be aligned with "Filterkaffee" and "Klein" and have the subtitle below.
Edit
Also here is the ListItem's code:
<ListItem
title={item.name}
leftElement=<Text style={styles.amount}>{item.amount}x</Text>
rightTitle={`${item.price.label}`}
subtitle={`${
item.items.length > 0
? item.customChoiceItems.reduce((acc, customChoiceItem, index, arr) => {
acc += customChoiceItem.name;
acc += index < arr.length - 1 ? "\n" : "";
return acc;
}, "")
: null
}`}
onPress={() => {}}
/>

Since you're using the leftElement prop on the ListItem component; I'm assuming you're using version 1.0.0-beta5 of react-native-elements.
The ListItem component has a containerStyle prop that you can use to control the styling of the container. By default, it has an alignItems: 'center' rule that allows the contents of the ListItem to be centred vertically. Since you want to align them to the top, you can use alignItems: 'flex-start'.
<ListItem
title="Filterkaffee"
leftElement={<Text style={styles.amount}>1x</Text>}
subtitle="Medium Roast Schokosojakeks"
rightTitle="Klein"
containerStyle={{ alignItems: 'flex-start' }}
/>

Related

Different numColumns for different parts of Flatlist

I would like to render a React Native Flatlist where the first two elements span the entire width of the screen while all consecutive elements span half the screen. Like this:
Is there a way to do this with one Flatlist? If not, what is the best way to do something like this? Preferably without a Scrollview.
You can't have multiple column numbers in one FlatList but you could achieve what you want by extracting out the first two elements from your data structure and rendering them as a header using the ListHeaderComponent property on FlatList. Then you can render the rest of your array as a regular FlatList.
You need to first redesign your data structure. Then you can do it with View and defined width?
const data = [
{
fields: 'SingleColumn',
},
{
fields: ['First Column','Second Column']
}
]
const renderItem = ({ item }) => {
return <View>
{ somecondition ? <View>
<View style={{ width: '50% }}>
...content...
</View>
<View style={{ width: '50%' }}>
...second column
</View> : <View style={{ width: '100%'}}>
..single column content
</View>
</View>
}
}

React Native - Horizontal Flatlist with column wrapper doesn't take flex properly as required?

I have a dynamic flatlist with values that should be rendered in the horizontal list with 3 columns. But, I am not able to make it display as I wanted.
I am trying the code as follow,
let data = ["item1", "item2", "item3", "item4", "item5", "item6", "item7", "item8"];
const { width } = Dimensions.get('window');
const itemWidth = (width - 12) / 3;
<FlatList
columnWrapperStyle={{ justifyContent: 'space-around', alignItems: 'flex-start' }}
numColumns={3}
data={data}
showsVerticalScrollIndicator={false}
showsHorizontalScrollIndicator
keyExtractor={(item, index) => `${index}${item}`}
renderItem={(item) => {
return (
<View style={{ flex: 1, backgroundColor: '#ddd', minWidth: itemWidth, maxWidth: itemWidth }}>
<Text >
Hello World
</Text>
</View>
);
}}
/>
But, the output is not as I wanted.
Let say, if the list is the length of multiple of 3 like 6,9,12 it works as I wanted.
But, if the list has length 8 first two rows are rendered okay. But, the third row is giving full space to the remaining two items. Which I don't want.
Currently i am geeting output as follow
But the output should be like,
Can anyone suggest a workaround?
Thanks.
See i can provide you one logical solution, and i'm assuming you want to plot the text inside the Flatlist. For this kind of scenarios, you would need to append an empty div for the respective empty slots.
If you want the numOfColumns to be 3,
let data = ["item1", "item2", "item3", "item4", "item5", "item6", "item7", "item8"];
First check the remainder and num of rows to be added by
let numOfRowsToBeAdded = 3-(data.length%3);
// here im ommitting if we get 0 as remainder as its not required
if(numOfRowsToBeAdded){
for(let i=0;i<numOfRowsToBeAdded;i++){
data.push(null);
}
}
Hope you got the logic. feel free for doubts. ill help
Since you calculate itemWidth manually, you can use justify: flex-end for your columnWrapperStyle and then add a marginRight: 6 to every first and second item in every row:
renderItem={(item, index) => {
const isThirdColumn = (index + 1) % 3 === 0;
const marginRight = isThirdColumn ? 0 : 6;
return (
<View style={{ marginRight, ...otherStyles }}>

How to make Horizontal SectionList RIGHT to LEFT Scroll react-native

I want to make an online shop, I need a Horizontal section List in react native, contains my products. here is my code. please help me to make it right to left scrolling.clothes is an array of objects contains my product's details.
export default class MySectionList extends Component{
render(){
return(
<SectionList
sections={Clothes}
horizontal={true}
showsHorizontalScrollIndicator={false}
renderItem={({item})=>(
<View>
<Image source={{uri:"item.image",width:'65%',height:200}}/>
<Text>{item.name}</Text>
<Text>{item.price}</Text>
</View>
)}
renderSectionHeader={({section})=>(
<Text>{section.title}</Text>)}
/>
)
}
}
this sectionList scrolls from left to right and I need another one scrolling from left to right.
I solve this by adding some styles. Unfortunately, I18NManager could not solve my problem so I used transform style and for all section list I applied transform: [{ scaleX: -1 }] and because of items inside sectionlist will be reversed, I applied this style again for item wrapper. something like this:
render(){
return(
<SectionList
sections={Clothes}
horizontal={true}
style={{ transform: [{ scaleX: -1 }] }}
showsHorizontalScrollIndicator={false}
renderItem={({item})=>(
<View style={{ transform: [{ scaleX: -1 }] }}>
<Image source={{uri:"item.image",width:'65%',height:200}}/>
<Text>{item.name}</Text>
<Text>{item.price}</Text>
</View>
)}
renderSectionHeader={({section})=>(
<Text>{section.title}</Text>)}
/>
)
}
}
This is a hacky way but I did not find another solution for my problem.
I hope this can help you
If your app language is right to left please set app support to use rtl with
I18NManager.allowRTL(true)
I18NManager.forceRTL(true)
to make section list or flat list scroll from right to left, Otherwise this cannot happen. There are another ways to solve this issue but it's not systematic! Like use inverted prop or direction style.
I had a similar demand for the right-to-left functionality. I used horizontal FlatList (in 2022) with an inverted property.
<FlatList
horizontal
data={diaryWeeksAll}
inverted
getItemLayout={(_data, index) => ({ length: width, offset: width * index, index })}
...
See documentation: https://reactnative.dev/docs/flatlist#inverted

React native TouchableHighlight ignore the first item

I have used TouchableHighlight for the FlatList in React native. Here used to display cities which will be returned by an API. But when each item in the flat list is touched only the 1st item is been ignored. But other items except the 1st one get highlighted when I press. Also, I am running the app on my device, not in an emulator. The screenshot of the flatlist
Code
export default class SearchResultsList extends Component {
render() {
return (
(this.props.list &&
<List containerStyle={{ borderTopWidth: 0, borderBottomWidth: 0 }} keyboardShouldPersistTaps={'always'}>
<FlatList
data={this.props.list}
renderItem={({ item }) => (
<TouchableHighlight
onPress={() => {
console.log(item.primaryText);
}}
underlayColor="#cca016"
>
<ListItem
title={item.primaryText}
subtitle={item.secondaryText}
containerStyle={{ borderBottomWidth: 0 }}
/>
</TouchableHighlight>
)}
/>
</List>)
);
}}
When I check without keyboardShouldPersistTaps={'always'} also the same issue is there.
it seems that you're using react-native-elements List component.
If it's the case, you should not place a FlatList inside the react-native-elements List.
Hope it helps

React Native: Correct scrolling in horizontal FlatList with Item Separator

ReactNative: v0.52.0
Platform: iOS
My FlatList code:
<FlatList
horizontal
pagingEnabled={true}
showsHorizontalScrollIndicator={false}
legacyImplementation={false}
data={this.props.photos}
renderItem={item => this.renderPhoto(item)}
keyExtractor={photo => photo.id}
ItemSeparatorComponent={this.itemSeparatorComponent}
/>
Item separator code:
itemSeparatorComponent = () => {
return <View style = {
{
height: '100%',
width: 5,
backgroundColor: 'red',
}
}
/>
}
And finally FlatList item component:
renderPhoto = ({ item, index }) => {
return (
<View style = {{ width: SCREEN_WIDTH, height: 'auto' }}>
<FastImage
style = { styles.photo }
resizeMode = { FastImage.resizeMode.contain }
source = {{ uri: item.source.uri }}
/>
</View>
)
}
But when scrolling, the FlatList makes an offset to the separator but not to the left edge of item:
And with each new element the FlatList adds the width of the all previous separators to offset:
How to make the FlatList component consider the width of the separator component in horizontal scrolling and make proper offset?
I had the same use-case. For anyone looking for a solution, here it is.
Step 1) Don't use ItemSeparatorComponent prop. Instead, render it inline in your renderItem component.
Step 2) (Key-point). Specify the width and height in the style prop of the FlatList. The width, in your case, should be SCREEN_WIDTH + 5.
Then Flatlist will automatically move the entire screen (photo + separator) away when pagination is enabled. So now your code should be like so:-
<FlatList
horizontal
pagingEnabled={true}
showsHorizontalScrollIndicator={false}
legacyImplementation={false}
data={this.props.photos}
renderItem={item => this.renderPhoto(item)}
keyExtractor={photo => photo.id}
style={{width: SCREEN_WIDTH + 5, height:'100%'}}
/>
Render photo code:-
renderPhoto = ({ item, index }) => {
return (
<View style = {{ width: SCREEN_WIDTH + 5, height: 'auto',
flexDirection:'row'}}>
<FastImage
style = { styles.photo }
resizeMode = { FastImage.resizeMode.contain }
source = {{ uri: item.source.uri }}
/>
{this. itemSeparatorComponent()}
</View>
)}
Item separator code:
itemSeparatorComponent = () => {
return <View style = {
{
height: '100%',
width: 5,
backgroundColor: 'red',
}
}
/>
}
If you still can't figure it out, then look at this component:
https://github.com/zachgibson/react-native-parallax-swiper
Try to go into the implementation, you will see that this guy has provided width and height to the Animated.ScrollView.
https://github.com/zachgibson/react-native-parallax-swiper/blob/master/src/ParallaxSwiper.js
Line number: 93 - 97
The top-level view you're returning in the renderPhoto function has a width of SCREEN_WIDTH, yet the ItemSeparatorComponent, which renders in between each item, is taking up a width of 5 as per your style definition. Consequently, for each additional item you scroll to, that initial offset will become 5 more pixels on the left.
To fix this, you can either remove the ItemSeparatorComponent completely, (as you already have pagingEnabled set to true), or set the width of the top-level view returned in renderPhoto equal to SCREEN_WIDTH - 2.5. That way you'll see half of the item separator on the right edge of one photo and the other half on the left edge of the next photo.
Actually, one other possible solution could be to remove the item separator, set the renderPhoto View's width to SCREEN_WIDTH + 5, and then include these additional properties inside the style: {paddingRight: 5, borderRightWidth: 5, borderRightColor: 'red'}. That way the red separator won't be visible until scrolling left and right, because of the pagingEnabled property.