my button doesn't work when I set it to absolute position, when setting is to be on top of a carousel... I suppose it is getting under something because when removing the absolute it works normally, but I don't know how to solve it
Short code:
export default class SpaceDetail extends React.Component {
state = {
optionSelected: "Fotos",
favorite: true,
};
render() {
return (
<ScrollView indicatorStyle="black">
<ContainerPhotoMap>
{this.state.optionSelected === "Fotos" ? <Carousel /> : <Maps />}
</ContainerPhotoMap>
<ButtonFavorite
onPress={() => {this.setState({favorite: !this.state.favorite})}}
>
<MaterialIcons
name={this.state.favorite ? "favorite" : "favorite-border"}
size={40}
color="white"
/>
</ButtonFavorite>
</ScrollView>
);
}
}
Short Style Code:
export const ContainerPhotoMap = styled(View)`
max-width: 200px;
`;
export const ButtonFavorite = styled(Button)`
position: absolute;
right: 0;
`;
Short carousel code:
export default class Carousel extends React.Component {
state = {
active: 0,
};
change = ( {nativeEvent} : {nativeEvent:any} ) => {
const slide = Math.ceil(
nativeEvent.contentOffset.x / nativeEvent.layoutMeasurement.width
);
if (slide !== this.state.active) {
this.setState({ active: slide });
}
};
render() {
return (
<View style={{ width, height }}>
<ScrollView
pagingEnabled
scrollEnabled
horizontal
onScroll={this.change}
showsHorizontalScrollIndicator
style={{ width, height }}
>
{images.map((image, index) => (
<Image
key={index}
source={{ uri: image }}
style={{ width, height, resizeMode: "cover" }}
/>
))}
</ScrollView>
<View
style={{
flexDirection: "row",
position: "absolute",
bottom: 0,
alignSelf: "center",
}}
>
{images.map((i, k) => (
<Text
key={k}
margin="3px"
color={k === this.state.active ? "white" : ""}
>
⬤
</Text>
))}
</View>
</View>
);
}
}
Style Carousel:
export const ViewCarousel = styled(View)`
width: width;
height: height;
position: relative;
`;
Button print on the right,
Related
Why my react-native-shadow-2 is not working ? i have installed npm i react-native-shadow-2 and react-native-svg but still its not working tell how to fix it i have also restarted my project i am using android i have also tried to do npx react-native link but that also did not work you can see whats the problem the shadow i have marked is wrong it should be like this
How its showing currently
my code
import React, { useRef } from 'react'
import {
View,
Text,
Image,
Animated,
FlatList,
} from 'react-native';
import {
Home,
Profile,
Search
} from '../../screens';
import { COLORS, FONTS, SIZES, constants } from '../../constants';
import { Shadow } from 'react-native-shadow-2';
const bottom_tabs = constants.bottom_tabs.map((bottom_tabs) => ({
...bottom_tabs,
ref: React.createRef()
}))
const MainLayout = () => {
const flatListRef = React.useRef()
const scrollX = React.useRef(new Animated.Value(0)).current;
function renderContent() {
return (
<View style={{
flex: 1,
}}
>
<Animated.FlatList
ref={flatListRef}
horizontal
pagingEnabled
snapToAlignment="center"
snapToInterval={SIZES.width}
decelerationRate="fast"
showsHorizontalScrollIndicator={false}
data={constants.bottom_tabs}
keyExtractor={item => `Main-${item.id}`}
onScroll={
Animated.event([
{ nativeEvent: { contentOffset: { x: scrollX } } }
], {
useNativeDriver: false
})
}
renderItem={({ item, index }) => {
return (
<View
style={{
height: SIZES.height,
width: SIZES.width
}}
>
{item.label == constants.screens.home && <Home />}
{item.label == constants.screens.search && <Search />}
{item.label == constants.screens.profile && <Profile />}
</View>
)
}}
/>
</View>
)
}
function renderBottonTab() {
return (
<View
style={{
marginBottom: 20,
paddingHorizontal: SIZES.padding,
paddingVertical: SIZES.radius
}}
>
<Shadow size={[SIZES.width - (SIZES.padding * 2), 85]}>
<View
style={{
flex: 1,
borderRadius: SIZES.radius,
backgroundColor: COLORS.primary3
}}
>
</View>
</Shadow>
</View>
)
}
return (
<View
style={{
flex: 1,
backgroundColor: COLORS.white,
}}
>
{/* Content */}
{renderContent()}
{/* Bottom Tab */}
{renderBottonTab()}
</View>
)
}
export default MainLayout;
I want 3 items to appear in each row and I want their size to be adjusted according to the screen itself, how can I do this?
I tried giving justifyContent to the flatlist columnWrapperStyle prop but the display turned out to be ridiculous
const renderSearchItem = ({
item: { id, type, title, original_title, poster },
}) => (
<Item
id={id}
type={type}
title={title == null ? original_title : title}
poster={poster}
navigation={navigation}
style={{ width: 115, height: 175 }}
/>
);
<FlatList
data={data?.datas}
renderItem={renderSearchItem}
keyExtractor={(item, index) => index.toString()}
key={search}
numColumns={3}
onEndReachedThreshold={1}
onEndReached={() => {
fetchMore({
variables: {
search,
offset: data?.datas?.length + 18,
},
updateQuery: (
previousResult,
{ fetchMoreResult }
) => {
if (
!fetchMoreResult ||
fetchMoreResult?.datas?.length === 0
) {
return previousResult;
}
return {
datas: previousResult?.datas?.concat(
fetchMoreResult?.datas
),
};
},
});
}}
ListHeaderComponent={headerComponent()}
showsVerticalScrollIndicator={false}
/>
You can get screen's width from Dimensions.
const width = Dimensions.get('screen').width
this will be the whatever the size of width the application running on.
export default function Item(props) {
const { id, type, title, poster, navigation, style } = props;
return (
<TouchableHighlight
style={styles.container}
onPress={() =>
navigation.navigate(
type == 'movie' ? 'MovieDetail' : 'SeriesDetail',
{
id,
title: title == null ? original_title : title,
}
)
}
>
<Image
style={[{ ...style }, { borderRadius: 5 }]}
source={{ uri: poster }}
/>
</TouchableHighlight>
);
}
const styles = StyleSheet.create({
container: {
alignItems: 'center',
marginBottom: 18,
marginLeft: 6,
},
});
I want a + button at the end of all images, in case 1 there should be only this 1 button on-screen if no image is available and else after the available images this button would be on last of all images, but I want to make this button look same as these images and also in row of 3
My code for the flat list is as below.
<FlatList
numColumns={3}
data={this.state.images}
renderItem={({ item }) => <SafeAreaView style={{ flex: 1, alignItems: 'center' }}>
<Image style={{ margin: 5, height: 120, width: 120 }}
source={{ uri:'data:image/png;base64,' + item.image }} />
</SafeAreaView>}
keyExtractor={item => item.id}
/>
You can put the + in a span whose position is absolute and wrap the last image in it. There's more styling to do here, but this is the start.
The function that adds the image should remove the span wrapper from the old last image and add it to the new one
<FlatList
numColumns={3}
data={this.state.images}
renderItem={({ item }) => <SafeAreaView style={{ flex: 1, alignItems: 'center' }}>
{(item.index + 1) % 3 == 0 ?
<TouchableOpacity onPress={() => { }}><Image style={{ margin: 5, height: 120, width: 120 }}
source={{ uri: 'data:image/png;base64,' + item.image }} />
{/* you can put your + icon image here */}
</TouchableOpacity>
:
<Image style={{ margin: 5, height: 120, width: 120 }}
source={{ uri: 'data:image/png;base64,' + item.image }} />
}
</SafeAreaView>}
keyExtractor={item => item.id}
/>
You just need to conditionally render the FlatList and add the button on the same "row" as the images.
I want to make this button look same as these images
Styling is up to you :)
Here's a little demo how it would work.
import React, { Component } from "react";
import {
Button,
StyleSheet,
Text,
View,
FlatList,
SafeAreaView
} from "react-native";
const data = [{ name: "first" }, { name: "second" }, { name: "third" }];
class App extends Component {
renderFlatList() {
const Item = ({ title }) => {
return (
<SafeAreaView style={styles.listItem}>
<Text style={{ padding: 10 }}>{title}</Text>
</SafeAreaView>
);
};
return (
<View>
<FlatList
numColumns={3}
data={data}
renderItem={({ item }) => ( <Item title={item.name} />)}
keyExtractor={item => item.id}
/>
</View>
);
}
render() {
return (
<View style={styles.container}>
{/* You probably are using state or props for the data, so this checking is just for the demo */}
{typeof data !== "undefined" && data.length > 0 && this.renderFlatList()}
<View>
{/* You could use <TouchableHighlight /> or whatever suits your needs*/}
<Button title={"+"} />
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flexDirection: "row"
},
listItem: {
backgroundColor: "gold",
}
});
export default App;
Hi I have a sectionList that is passed an array of colors + background imgs that are chosen at random to render as a background of each row item. When I swipe to access that view the colors flicker for a few seconds as the random selection is still occurring. Each time I return to the screen with the list, the colors will flicker for a few seconds then settle. how can I have no flickering and the random selection of color happen once at load?
class Main extends React.Component {
constructor(props, context) {
super(props, context);
// app state
this.state = {
listColor: [
['rgba(0,36,155,0.8)', 'rgba(26,0,87,0.8)'],
['rgba(155,0,0,0.8)', 'rgba(87,0,0,0.8)']],
}
}
_handleRandomIndex(arr) {
return arr[Math.floor(Math.random() * arr.length)]
}
_renderItem = ({item, section}) => (
<TouchableScale
style={styles.row}
onPress={this._onRowPress.bind(this, item)}
activeScale={0.94}
tension={0}
friction={3}
>
<View style={ styles.elevationLow } borderRadius={9} >
<ImageBackground source={{uri: this._handleRandomIndex(item.bgImgs).image_link }} borderRadius={9} style={ styles.imageBackground }>
<LinearGradient
colors={ this._handleRandomIndex(this.state.listColor) }
start={[0.1,0.1]}
end={[0.5,0.5]}
style={{ padding: 20, borderRadius: 9 }}>
</LinearGradient>
</ImageBackground>
</View>
}
</TouchableScale>
)
}
Because you are doing a Math.random every re-render. So whenever the render function calls, it is changing the color.
Change to this:
function _handleRandomIndex(arr) {
return arr[Math.floor(Math.random() * arr.length)]
}
class Main extends React.Component {
state = {
listColor: [
['rgba(0,36,155,0.8)', 'rgba(26,0,87,0.8)'],
['rgba(155,0,0,0.8)', 'rgba(87,0,0,0.8)']
]
}
_renderItem = ({ item, section }) => <Item item={item} listColor={this.state.listColor} />
}
class Item extends Component {
rando = _handleRandomIndex(this.props.listColor);
render() {
const { item } = this.props;
return (
<TouchableScale
style={styles.row}
onPress={this._onRowPress.bind(this, item)}
activeScale={0.94}
tension={0}
friction={3}
>
<View style={styles.elevationLow} borderRadius={9}>
<ImageBackground source={{ uri: this._handleRandomIndex(item.bgImgs).image_link }} borderRadius={9} style={styles.imageBackground}>
<LinearGradient
colors={this.rando}
start={[0.1, 0.1]}
end={[0.5, 0.5]}
style={{ padding: 20, borderRadius: 9 }}>
</LinearGradient>
</ImageBackground>
</View>
</TouchableScale>
)
}
}
Noitidart's answer will work but all the items will be randomized to same color, if you want each item a different color I think you need to do this:
_renderItem = ({item, section}) => {
const color = this._handleRandomIndex(this.state.listColor);
return (
<TouchableScale
style={styles.row}
onPress={this._onRowPress.bind(this, item)}
activeScale={0.94}
tension={0}
friction={3}
>
<View style={ styles.elevationLow } borderRadius={9} >
<ImageBackground source={{uri: this._handleRandomIndex(item.bgImgs).image_link }} borderRadius={9} style={ styles.imageBackground }>
<LinearGradient
colors={ color }
start={[0.1,0.1]}
end={[0.5,0.5]}
style={{ padding: 20, borderRadius: 9 }}>
</LinearGradient>
</ImageBackground>
</View>
}
</TouchableScale>
)
}
I want to let the logo center in the tarbar, and that is overflow tabbar on the top. How to do it ? .......
...................................................................................................................................................
import React from 'react';
import TabNavigator from 'react-native-tab-navigator';
import {
View,
Text,
StyleSheet,
Image
} from 'react-native';
class App extends React.Component {
constructor(props){
super(props)
this.state={
selectedTab:'首页',
}
}
render() {
return (
<View style={styles.container}>
<TabNavigator tabBarStyle={styles.tabBarStyle} tabBarShadowStyle={styles.tabBarShadowStyle}>
<TabNavigator.Item
selected={this.state.selectedTab === '首页'}
title="首页"
selectedTitleStyle={styles.selectedTitleStyle}
renderIcon={() => <Image style={styles.tabBarIcon} source={require('../../res/images/icons/home.png')}/>}
renderSelectedIcon={() => <Image style={[styles.tabBarSelectedIcon ]} source={require('../../res/images/icons/home.png')}/>}
onPress={() => this.setState({ selectedTab: '首页' })} >
<Text>首页</Text>
</TabNavigator.Item>
<TabNavigator.Item
selected={this.state.selectedTab === '产品'}
title="产品"
selectedTitleStyle={styles.selectedTitleStyle}
renderIcon={() => <Image style={styles.tabBarIcon} source={require('../../res/images/icons/product.png')}/>}
renderSelectedIcon={() => <Image style={[styles.tabBarSelectedIcon ]} source={require('../../res/images/icons/product.png')}/>}
onPress={() => this.setState({ selectedTab: '产品' })} >
<Text>产品</Text>
</TabNavigator.Item>
<TabNavigator.Item
renderIcon={() => <Image style={styles.logoIcon} source={require('../../res/images/icons/logo_tab.png')}/>} >
</TabNavigator.Item>
<TabNavigator.Item
selected={this.state.selectedTab === '活动'}
title="活动"
selectedTitleStyle={styles.selectedTitleStyle}
renderIcon={() => <Image style={styles.tabBarIcon} source={require('../../res/images/icons/activity.png')}/>}
renderSelectedIcon={() => <Image style={[styles.tabBarSelectedIcon ]} source={require('../../res/images/icons/activity.png')}/>}
onPress={() => this.setState({ selectedTab: '活动' })} >
<Text>活动</Text>
</TabNavigator.Item>
<TabNavigator.Item
selected={this.state.selectedTab === '我的'}
title="我的"
selectedTitleStyle={styles.selectedTitleStyle}
renderIcon={() => <Image style={styles.tabBarIcon} source={require('../../res/images/icons/profile.png')}/>}
renderSelectedIcon={() => <Image style={[styles.tabBarSelectedIcon ]} source={require('../../res/images/icons/profile.png')}/>}
onPress={() => this.setState({ selectedTab: '我的' })} >
<Text>我的</Text>
</TabNavigator.Item>
</TabNavigator>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1
},
tabBarStyle: {
backgroundColor: '#fff',
overflow: 'visible',
},
tabBarShadowStyle: {
height: 0,
},
selectedTitleStyle: {
color: '#b42325',
},
logoIcon: {
zIndex: 9999,
position: 'absolute',
top: -50,
left: -25,
width: 60, height: 60,
},
tabBarIcon: {
width: 26, height: 26,
resizeMode: 'contain',
tintColor: '#5f5f5f',
},
tabBarSelectedIcon: {
width: 26, height: 26,
resizeMode: 'contain',
tintColor: '#b42325',
}
});
export default App;
Current like this
And I want to like this..
Use custom navigator to customize your tab view could to the trick, but it will include more effort.
Here is the docs https://reactnavigation.org/docs/navigators/custom
And here is a small example https://github.com/react-community/react-navigation/blob/master/examples/NavigationPlayground/js/CustomTabs.js