Currently my items are all to the left as they should be by default. I can not seem to move it to the right side. For reference, I have attached an image
https://ibb.co/fYFPMFJ
I have already tried styling it with tabStyle and using alignSelf: 'flex-end' alignItems: 'flex-end' flexDirection: 'row', justifyContent: 'flex-end'
Here is the code:
const TabNavigator = createMaterialTopTabNavigator({
ރިޕޯޓު: {screen: MainScreenCategoryTabNavigator, params:{categoryID: 1004}},
ދީން: {screen: MainScreenCategoryTabNavigator, params:{categoryID: 1003}},
ސިޔާސީ: {screen: MainScreenCategoryTabNavigator, params:{categoryID: 1002}},
ޙަބަރު: {screen: MainScreenTabNavigator, params:{categoryID: 1000}},
},
{
initialRouteName:'ޙަބަރު',
lazy: true,
tabBarOptions: {
labelStyle: {
fontSize: 16,
fontFamily: 'MV_Waheed',
fontWeight: "200"
},
tabStyle: {
width: 60,
textAlign: 'right'
},
}
},
);
Like I mentioned above, and the reference to the image attached, I would like to move the tabs to the right instead of left. How can I achieve this?
Thanks!
Fixed the issue. The problem for me was that I could not align it to the right. I removed the width and that solved my problem. That was all that needed to be done
One of the variants it's to use your own component as a tabBar. In this way it's easier to customize it as you wish.
import { createBottomTabNavigator, BottomTabBar } from 'react-navigation-tabs';
const TabBarComponent = (props) => (<BottomTabBar {...props} />);
const TabScreens = createBottomTabNavigator(
{
tabBarComponent: props =>
<TabBarComponent
{...props}
style={{ borderTopColor: '#605F60' }}
/>,
},
);
Related
I 'm trying to make a translate animation in React Native.
Here is my code
const scrollX = React.useRef(new Animated.Value(0)).current;
<Animated.ScrollView
horizontal
snapToInterval={width}
onScroll={Animated.event(
[{ nativeEvent: { contentOffset: { x: scrollX } } }],
{ useNativeDriver: false }
)}
scrollEventThrottle={16}
></Animated.ScrollView>
<Animated.View style={{ transform: [{ translateX: multiply(scrollX, -1) }] }}>
<Text>Some text</Text>
</Animated.View>
I am getting this error transform with key of translatex must be a number
If I change multiply(scrollX, -1) to scrollX the animation is reversed,
How can I fix this issue ?
i had this issue,Just because i forgot to give Animated.View
I fixed it by changing the import of multiply from react-native-reanimated to Animated
const test = () => {
const translation = useRef(new Animated.Value(0)).current;
useEffect(()=> {
Animated.timing(translation, {
toValue: 200,
useNativeDriver: true,
}).start();
}, []);
return (
<>
<Animated.View style={{
width: 150, height: 150, backgroundColor: 'red', borderRadius: 8, margin: 10,
transform: [{translateX: translation}]
}} />
</>
);
}
export default test;
Need to Give where you want to do Animation -> Animated.[Component Name] -> E.g: Animated.View / Animated.Text / Animated.Button
You need to import Animated from react-native and not from react-native-reanimated
i have list in which i want to show image like this
this is my list component I have giving correct path but nothin happens have giving width and height but no luck
import React from "react";
import {
View,
Text,
StyleSheet,
Button,
Image,
ImageBackground,
} from "react-native";
import colors from "../config/colors";
import AppText from "./AppText";
export default function ListItem({ image, title, sutitle }) {
return (
<View style={styles.container}>
<Image style={styles.image} source={image} />
<View style={styles.tittleContainer}>
<AppText style={styles.title}>{title}</AppText>
<AppText style={styles.subtitle}>{sutitle}</AppText>
</View>
</View>
);
}
const styles = StyleSheet.create({
image: {
width: 70,
height: 70,
borderRadius: 35,
marginRight: 10,
},
container: {
flexDirection: "row",
},
sutitle: {
fontWeight: "bold",
color: colors.red,
},
tittleContainer: {
padding: 20,
},
title: {
fontWeight: "bold",
marginBottom: 7,
},
});
I am unable to render image on my screen
the issue is while providing props to ListItem component you're passing "Image". and while using it in the component you're using "image".
I hope this solves your issue.
Image is working copy past your code nothing else,
check your image path correctly
https://snack.expo.io/#jsfit/image
export default function ListItem({ image, title, sutitle }) { in this params you are getting the image as lower i and when you are passing with Image as capital I.
I'm using DrawerNavigator and, as long as I want to navigate to a new screen, all's fine.
Now I want to add a drawer item which does not navigate to a new screen but simply triggers an action (in general). Specifically, I want to use 'react-native' Share functionality.
I got this to work but I think the solution is not a very good one. Here's what I got so far:
const myContentComponent = props => (
<ScrollView alwaysBounceVertical={false}>
<SafeAreaView style={{ flex: 1 }} forceInset={{ top: 'always', horizontal: 'never' }}>
<DrawerItems {...props} />
<TouchableItem
key="share"
onPress={() => {
Share.share(
{
message: 'YO: this will be the text message',
url: 'http://tmp.com',
title: 'This will be the email title/subject',
},
{
// Android only:
dialogTitle: 'This will be the title in the dialog to choose means of sharing',
},
);
props.navigation.navigate('DrawerClose');
}}
delayPressIn={0}
>
<SafeAreaView forceInset={{ left: 'always', right: 'never', vertical: 'never' }}>
<View style={[{ flexDirection: 'row', alignItems: 'center' }, {}]}>
<View style={[{ marginHorizontal: 16, width: 24, alignItems: 'center' }, { opacity: 0.62 }, {}]}>
<Icon name="share" />
</View>
<Text style={[{ margin: 16, fontWeight: 'bold' }, { color: DrawerItems.defaultProps.inactiveTintColor }]}>Share</Text>
</View>
</SafeAreaView>
</TouchableItem>
</SafeAreaView>
</ScrollView>
);
const RootStack = DrawerNavigator(
{
Settings: {
screen: SettingsScreen,
},
},
{
contentComponent: myContentComponent,
},
);
Basically, I am creating a new contentComponent based off of the default:
https://github.com/react-navigation/react-navigation/blob/v1.5.8/src/navigators/DrawerNavigator.js#L16-L22
I am copying the styles and element structure of a normal drawer item (everything under TouchableItem) - all this so I can define my own onPress which does the share logic and closes the drawer.
There has to be a better way right? What happens if I want the "Share" drawer item somewhere amongst the drawer items rendered by DrawerItems (the ones that support navigation)? Right now I can only work around the items rendered by DrawerItems. Besides, copying so much code from react-navigation seems like really bad form.
I just want an item which does some custom logic instead of rendering a screen.
I am not sure will it be helpful?
I used onPress event for logout like this way. It's no need to render a new DrawerItems
const DrawerNavigator = createAppContainer(createDrawerNavigator({
Logout: {
screen: EmptyScreenForLogoutConfirmation,
navigationOptions: ({ navigation }) => ({
tabBarLabel: 'Logout',
drawerIcon: ({ tintColor }) => <Icon name={"ios-cog"} size={26} />,
}),
},
},
{
contentComponent:(props ) => (
<DrawerItems {...props}
onItemPress = {
( route ) =>
{
if (route.route.routeName !== "Logout") {
props.onItemPress(route);
return;
}
return Alert.alert( // Shows up the alert without redirecting anywhere
'Confirmation required'
,'Do you really want to logout?'
,[
{text: 'No'},
{text: 'Yes', onPress: () => { props.navigation.navigate('Logedout'); }},
]
)
}
}
/>
),
contentOptions: {
activeTintColor: '#e91e63',
}
},))
On Android 4.4, ListView separator lines are inconsistent in thickness, and some do not render.
I can't see how this can be a code issue, this is how I render them:
separator: {
height: 1,
backgroundColor: 'grey',
}
...
<ListView
renderSeparator={(sectionID, rowID) =>
<View key={`${sectionID}-${rowID}`} style={styles.separator} />
}
.../>
Here is a screenshot of a View with this problem:
This issue does not happen on iOS or Android 6.
Anyone had this problem before?
Update
I did a test, this is not Android4 issue. It happens on all API version when running on Nexus One device (in android emulator)
I had this issue on iOS and worked around it by adding a hairline margin, like so:
<View
style={{
...styles,
borderWidth: StyleSheet.hairlineWidth,
margin: StyleSheet.hairlineWidth,
}}
>
{// ...row content}
</View>
Just give the height:hairlineWidth in style
I had the same issue and solved changing the view height from a number to StyleSheet.hairlineWidth as some folks said before. Trying to be more visual/specific:
Before:
renderItemSeparator() {
return (
<View style={{ height: .2, backgroundColor: 'rgba(0,0,0,0.3)' }} />
);
}
After:
renderItemSeparator() {
return (
<View style={{ height: StyleSheet.hairlineWidth, backgroundColor: 'rgba(0,0,0,0.3)' }} />
);
}
Actually there is no fix. It's RN "render-canvas-bug".
But I found hack solution.
<ListView
style={Style.listView}
dataSource={data}
renderRow={(data) => this._renderRow(data)}
/>`
Style.listView: {
backgroundColor: '#fff',
}, // or another backgroundColor you need
Then:
_renderRow(goods) {
return (
<View key={'goods_' + goods.id} style={Style.listView_item}>
<TouchableOpacity or View or ...
style={[Style.flex, Style.flexRow, Style.separatorRow, Style.u_paddingVerticalS, Style.u_middle]}
onPress={() => this._xyz(goods)}>
<View>
<AppFont>{goods.name}</AppFont>
</View>
</TouchableOpacity or View or ...>
</View>
);
}
Only important TouchableOpacity style is Style.separatorRow to render your separator. This style should be inside listView_item, where you can use another styles.
listView: {
backgroundColor: '#fff',
},
listView_item: {
paddingHorizontal: em(1.5),
},
flex: {
flex: 1,
},
flexRow: {
flexDirection: 'row',
},
separatorRow: {
marginBottom: 1,
borderBottomWidth: 1,
borderBottomColor: Colors.canvasColor,
},
You can use StyleSheet.hairlineWidth instead of 1 but it's not a must.
I reported it on GitHub
My workaround was to style the containing view and text like this:
const styles = StyleSheet.create({
rowViewContainer: {
flex: 1,
paddingRight: 15,
paddingTop: 13,
paddingBottom: 13,
borderBottomWidth: 0.5,
borderColor: '#c9c9c9',
flexDirection: 'row',
alignItems: 'center',
},
rowText: {
marginLeft: 15,
},
});
This is the ListView:
<ListView
dataSource={this.state.dataSource}
renderRow={(data) => <View style={styles.rowViewContainer}>
<Text style={styles.rowText}>
{data.bb_first_name}
</Text>
</View>}
/>
Looks nice:
This happens because you have empty rows in your data source. You can style your separators to see it
To avoid this just filter your data.
I faced the same issue when trying to render a Divider with a width of 0.5.
It rendered properly on devices with pixel ratio of 2 (e.g. iPhone SE 2nd gen.) but rendered random width on devices with pixel ratio of 3 (e.g. iPhone 12).
As suggested by other answers, using Stylesheet.hairlineWidth fixes the random width issue but the problem was that the width was thinner than 0.5 on devices with pixel ratio of 3.
So this fixed my problem:
import { PixelRatio, View } from 'react-native';
...
export const Divider = () => {
const width = PixelRatio.roundToNearestPixel(0.5);
...
return <View style={{ width }} ... />
}
I am building my first app with React Native, an app with a long list of images. I want to show a spinner instead of image while image is loading. It is sounds trivial but i didn't found a solution.
I think for a spinner i suppose to use ActivityIndicatorIOS , but how am i combining it with an Image component?
<Image source={...}>
<ActivityIndicatorIOS />
</Image>
Is this a right direction? Am i missing something?
I will share my solution
<View>
<Image source={{uri: this.state.avatar}} style={styles.maybeRenderImage}
resizeMode={"contain"} onLoadStart={() => this.setState({loading: true})}
onLoadEnd={() => {
this.setState({loading: false})
}}/>
{this.state.loading && <LoadingView/>}
</View>
LoadingView.js
export default class LoadingView extends Component {
render() {
return (
<View style={styles.container}>
<ActivityIndicator size="small" color="#FFD700"/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
position: "absolute",
left: 0,
right: 0,
top: 0,
bottom: 0,
opacity: 0.7,
backgroundColor: "black",
justifyContent: "center",
alignItems: "center",
}
});
Here is a complete solution to providing a custom image component with a loading activity indicator centered underneath the image:
import React, { Component } from 'react';
import { StyleSheet, View, Image, ActivityIndicator } from 'react-native';
export default class LoadableImage extends Component {
state = {
loading: true
}
render() {
const { url } = this.props
return (
<View style={styles.container}>
<Image
onLoadEnd={this._onLoadEnd}
source={{ uri: url }}
/>
<ActivityIndicator
style={styles.activityIndicator}
animating={this.state.loading}
/>
</View>
)
}
_onLoadEnd = () => {
this.setState({
loading: false
})
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
activityIndicator: {
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
}
})
I will share my own solution based only on CSS manipulation, which in my opinion is easy to understand, and the code is pretty clean. The solution is a little similar to other answers, but doesn't require absolute position of any component, or creating any additional components.
The idea is to switch between showing an <Image> and <ActivityIndicator>, based on some state variable (isImageLoaded in the snippet below).
<View>
<Image source={...}
onLoad={ () => this.setState({ isImageLoaded: true }) }
style={[styles.image, { display: (this.state.isImageLoaded ? 'flex' : 'none') }]}
/>
<ActivityIndicator
style={{ display: (this.state.isImageLoaded ? 'none' : 'flex') }}
/>
</View>
Also you should set image size using flex property (otherwise image will be invisible):
const styles = StyleSheet.create({
image: {
flex: 1,
}
});
Note that you don't have to initiate the isImageLoaded variable to false in the constructor, because it will have undefined value and the if conditions will act as expected.
Just ran into the same issue. So basically you have the correct approach, but the indicator should of course only be rendered when the image is loading. To keep track of that you need state. To keep it simple we assume you have just on image in the component an keep the state for it in the same component. (The cool kids will argue you should use a higher order component for that and then pass the state in via a prop ;)
The idea then is, that your image starts out loading and onLoadEnd (or onLoad, but then the spinner gets stuck on error, which is fine or course) you re-set the state.
getInitialState: function(){ return { loading: true }}
render: function(){
<Image source={...} onLoadEnd={ ()=>{ this.setState({ loading: false }) }>
<ActivityIndicatorIOS animating={ this.state.loading }/>
</Image>
}
You could also start out with { loading: false } and set it true onLoadStart, but I'm not sure what the benefit would be of that.
Also for styling reasons, depending on your layout, you might need to put the indicator in a container view that is absolutely positioned. But you get the idea.
Yes, deafultSource and loadingIndicatorSource is not working properly. Also image component cannot contain children. Try this solutions => https://stackoverflow.com/a/62510268/11302100
You can simply just add a placeholder
import { Image } from 'react-native-elements';
<Image
style={styles(colors).thumbnail}
source={{ uri: event.image }}
PlaceholderContent={<ActivityIndicator color={colors.indicator} />}
/>
const [imageLoading, setIsImageLoading] = useState(true);
<View>
<View
style={[
{justifyContent: 'center', alignItems: 'center'},
imageLoading ? {display: 'flex'} : {display: 'none'},
]}>
<ActivityIndicator />
</View>
<Image
source={{uri: ""}}
onLoadEnd={() => {setIsImageLoading(false)}}
style={[
imageStyle,
imageLoading ? {display: 'none'} : {display: 'flex'},
]}
/>
</View>