I am trying to have a react native collapsible header with scrollview and a fixed button on the bottom - react-native

I have a react native screen. Where I want the collapsible header to expand and collapse based on the scrolling of the scrollview but I also want a fixed button at the ned of the screen. Now I tried giving my scrollview a flex:1 but it seems to make the scrollview stop scrolling. and the scrollview takes up all the available space of the parent so even if I give flex 1 to a view wrapping the scrollview it does not scroll.
I have tried a solution by giving the parent height of 70% but I want the button to be fixed on the bottom. How do I achieve this.
I currently have this code
<SafeAreaView edges={["bottom"]}>
<Animated.View
style={{
height: interpolatedHeight,
}}
>
<HeaderComponent />
</Animated.View>
<Animated.ScrollView
style={[
CourseDetailStylesheet.scrollingContainer,
{
borderTopLeftRadius: borderRadius,
borderTopRightRadius: borderRadius,
flex: 1,
},
]}
scrollEventThrottle={16}
onScroll={Animated.event(
[{ nativeEvent: { contentOffset: { y: scrollOffsetY } } }],
{ useNativeDriver: false }
)}
>
{/** Rest of the content */}
</Animated.ScrollView>
<Button style={CourseDetailStylesheet.ctaButton} title={"Fixed Button"} />
</SafeAreaView>;
I am trying to achieve this

Related

Float an image zooming on an "instagram-like" news feed in react-native

I'm working on an "instagram-like" news feed for an existing react native (0.63.4) application. At this stage I'm using the react-native-gesture-handler (1.10) to handle the pinch/zoom functionality using its PinchGestureHandler and FlatList implementations.
I have an outer vertical flatlist for scrolling the new items and, for each item, an inner horizontal flat list to scroll the images left and right.
If I scale the image inline then it works fine, though it's a little slow due to having to re-layout all the other items.
What I'd like to do is "float" the image above everything else and then snap back after zooming. I can do all of that, except floating the image. I've tried setting overflow:'visible' on the entire tree, but it doesn't help zIndex and elevation also don't seem to help.
Visually I'd like to (kind of) pop the image out while zooming, then it can snap back at the end. How do I do this?
--Implementation details:
The feed is just an array of NewsItem:
interface NewsItem {
id: string,
title: string,
images: NewsImage[],
datePublished: Date
}
interface NewsImage {
id: string,
uri: string,
width: number,
height: number,
ref: RefObject<PinchGestureHandler>
}
imageRefs is a flattened list of references for all the images.
The main layout is like this (slightly simplified):
<View>
<FlatList
waitFor={imageRefs}
data={newsFeed}
keyExtractor={item => item.id}
renderItem={({item}) => <NewsItem item={item} /> } />
</View>
NewsItem
<View>
<Text>{props.item.title}</Text>
<FlatList
horizontal={true}
waitFor={props.item.images.map(img => img.ref)}
data={props.item.images}
keyExtractor={img => img.id}
renderItem={({item})} => <NewsImage info={item} />
/>
</View>
NewsImage has all the code to handle the pinch/zoom transform stored in the variables:
scale
scaledWidth
scaledHeight
xScaledTranslate
yScaledTranslate
With the layout:
<View style={{
width: info.width * minScale,
height: info.height * minScale,
position: 'relative',
}}>
<Animated.View style={{
position:'absolute',
overflow:'visible',
width:scaledWidth,
height:scaledHeight,
}}>
<PinchGestureHandler
onGestureEvent={pinchGestureEventHandler}
onHandlerStateChange={pinchStateEventHandler}
ref={ref}
>
<Animated.Image
defaultSource={require('../Shared/assets/logos/bootsplash_logo.png')}
source={info}
style={{
width: info.width,
height: info.height,
overflow:"visible",
transform: [
{translateX: xScaledTranslate},
{translateY: YScaledTranslate},
{scale: scale},
]
}}
resizeMode='cover'
/>
</PinchGestureHandler>
</Animated.View>
</View>
I dunno did you solved this issue, but simply you can't do that with FlatList.
I had the similar issue and solved it to converting my FlatList to a ScrollView
You can use this: https://github.com/postillonmedia/react-native-instagram-zoomable
It's a JS implementation so you can also modify the code as needed. It zooms the view/image/component above everything on the screen. It creates a clone of the element and uses PanGestures to zoom

Position absolute children on flatlist element in React Native (expo)

I want to make a little game when some circles comes from the top of the screen. After they appear they will drag down until they go out of the screen.
To make that i have a flatlist which contains all of the circles
<FlatList scrollEnabled={false}renderItem={this.renderItem}data={this.state.elements} />
Then in the render item I insert the circle item view
renderItem = ({item}) => (
<Circle
apparitionTime={new Date().getTime() / 1000}
id={item.id}
removeCircle={this.removeCircle}
updateScore={this.updateScore}/>
);
A circle item looks like this :
<Animated.View style={[/*this.moveAnimation.getLayout(),*/ styles.animatedView]}>
<TouchableOpacity style={styles.circleStyle} onPress={() => this.prepareToSend()}>
<View style={styles.absoluteView}>
</View>
<Image style={styles.image} source={require('../assets/images/music.png')}/>
</TouchableOpacity>
</Animated.View>
I use the animated view to make them scrolling all over the view.
I want the animated view to be on position absolute,but no matter what i've tried after sending the animated view to position absolute, the element disappear
animatedView: {
top: 0,
zIndex: 100,
width: 75,
height: 75,
position: "absolute", // does not work
},
Any Ideas ? Thank you
Position absolute didn't work inside a flatlist.
Now how to render positional elements inside it !!!!!!!....
Alternatively, you can use alignSelf: 'flex-end' or alignSelf:
'flex-start' and further you can place it by using margin/padding
inside the view. More you can read here about absolute not working in
their official docs

React Native Expo Horizontal and Vertical Scrolling - Android and iOS

I have implemented horizontal scrolling with the following code: https://snack.expo.io/H1CnjIeDb
How to implement multiple rows of horizontal red-blue boxes (keeping horizontal scrolls), with rows that can be scrolled vertically.
Additionally, how do I programtically add <View style={styles.view} /> inside scroll view, for both horizontal and vertical scrolling?
you can achieve multiple rows of horizontal red-blue boxes (keeping horizontal scrolls), with rows that can be scrolled vertically by Nested scroll view
you can achieve programmatically add inside scroll view, for both horizontal and vertical scrolling by using Map function. Check Expo snack. I have implemented what you need.
<ScrollView
ref={scrollView => {
this.scrollView = scrollView;
}}
style={styles.container}
//pagingEnabled={true}
horizontal={false}
decelerationRate={0}
snapToInterval={width - 60}
snapToAlignment={'center'}
contentInset={{
top: 0,
left: 30,
bottom: 0,
right: 30,
}}>
{array.map(item => {
return (
<ScrollView horizontal={true}>
{array.map(item => {
return (
<View style={item % 2 === 0 ? styles.view : styles.view2} />
);
})}
</ScrollView>
);
})}
</ScrollView>
If answer satisfies you, Upvote it :-)

How can i charge color icon navigation bar #shoutem/ui

I tried to create react native project and UI extends Component of #shoutem/ui,
But when i used NavigationBar of #shoutem/ui, i can't change color of content inside NavigationBar, like picture below here, News always got black color, how to change it to White color?
Here is my code:
<NavigationBar
style={{
container: {
position: 'relative',
width: Dimensions.get('window').width,
}
}}
leftComponent={(
<TouchableOpacity
style={{ paddingLeft: 10 }}
onPress={() => { this.props.navigation.navigate('DrawerOpen'); }}
>
<Image
styleName="small-avatar"
source={{ uri: 'https://scontent-hkg3-1.xx.fbcdn.net/v/t1.0-1/p160x160/17021999_1653807211588081_745686882439263143_n.jpg?oh=1dc68f938a820a9ccfea09033c0f4e34&oe=5987630B' }}
/>
</TouchableOpacity>
)}
centerComponent={
<DropDownMenu
selectedOption={this.state.selectedChannel ?
this.state.selectedChannel : this.state.channel[0]}
options={this.state.channel}
onOptionSelected={(channel) => this.onChoiceChannel(channel)}
titleProperty="name"
valueProperty="id"
/>}
/>
And here is my result:
Please help me fix this! Or suggest me someway can resolve it!
Thanks you guys so much!
The text color in NavigationBar is determined by the background color. If the background color is dark enough, NavigationBar will switch it's components to the "light-content", as seen in:
AppName/node_modules/#shoutem/ui/components/NavigationBar.js
function chooseBarStyle(bgColor) {
return color(bgColor).isDark() ? 'light-content' : 'default';
}
If you want to edit the color manually, you'll have to edit:
AppName/node_modules/#shoutem/ui/theme.js
title: {
fontFamily: 'Rubik-Regular',
fontStyle: 'normal',
fontWeight: 'normal',
fontSize: 20,
color: '#222222', //edit color here for your Title
}
Edit in response to comment:
The icon color is also edited in:
AppName/node_modules/#shoutem/ui/theme.js
navBarIconsColor: '#222222' //edit this line for your Icon

React Native ScrollView snapping back to top after release

I have used ScrollView in other apps adding just a style={styles.container} with the styles. However in this app I am creating in my styles I have alignItems:'flex-start' which throws an error with just style={styles.container} and instead you need to pass in alignItems:'flex-start' through contentContainerStyle={styles.container}.
Error: Invariant Violation: ScrollView child layout (["alignItems"]) must by applied through the contentContainerStyle prop.
However when I add contentContainerStyle when scrolling down in the view, once the finger is lifted off the phone (or release of the mouse in simulator), the scroll automatically goes back to the top. If I just use style={styles.container} and take out the alignItems:'flex-start' it scrolls correctly, but my items in the UI are not laid out how I need them. What is causing it to scroll back to the top with contentContainerStyle and is there a fix?
render:
var _that = this;
var iconsToShow = icons.map(function (icon, i){
if(i < 81){
return (
<TouchableHighlight
onPress={() => _that.changeIcon(indexToChange, icon)}
underlayColor='#F7F7F7'
key={i}>
<Text style={styles.iconText}><IonIcons name={icon} size={30} color="#555" /></Text>
</TouchableHighlight>
);
}
});
return (
<Carousel width={SCREEN_WIDTH} animate={false} indicatorColor="#444" inactiveIndicatorColor="#999" indicatorAtBottom={false} indicatorOffset={16}>
<View>
<ScrollView contentContainerStyle={styles.container}>{iconsToShow}</ScrollView>
</View>
<View>
//next page for carousel
</View>
</Carousel>
);
I figured out how to get it to scroll. Instead of having the View wrapping the ScrollView and the ScrollView having any flex styling or alignItems:'flex-start' with contentContainerStyle={styles.container}, put that on the View which is a child of the ScrollView and just use style= instead of contentContainerStyle=.
render:
<ScrollView style={styles.container}>
<Text style={styles.goalName}>{goal}</Text>
<View style={styles.viewContainer}>
{iconsToShow}
</View>
</ScrollView>
Styling:
var styles = StyleSheet.create({
container: {
backgroundColor: 'transparent',
paddingLeft:20,
paddingRight:20
},
viewContainer:{
flexDirection:'row',
flexWrap: 'wrap',
alignItems: 'flex-start',
flex: 1
},
iconText:{
paddingLeft:15,
paddingRight:15,
paddingTop:15,
paddingBottom:15
},
goalName:{
textAlign:'center',
marginTop:40,
marginBottom:10,
fontSize:20
}
});
If someone still couldn't fix the problem, try put {flex: 1} into "all" parents of the ScrollView