I am trying to use react-native-snap-carousel but however, the swiping effect is not working as expected - it is often difficult to swipe left and right, it requires user to swipe harder to move to another picture (as illustrated in the link below).
Swiping issue with React Native Snap Carousel
I am not able to find any documented soluton but I found one possible prop - swipeThreshold. I try various value, but still the issue persist.
Does anyone know the solution to this?
I suggest you to use react-native-image-slider.
it's flexible and easy to use.
https://www.npmjs.com/package/react-native-image-slider
I made a component named slider.js:
import React, { Component } from 'react';
import {
View,
StyleSheet,
Image,
} from 'react-native';
import ImageSlider from 'react-native-image-slider';
export default class Slider extends Component {
render() {
return (
<ImageSlider
loop
autoPlayWithInterval={3000}
images={this.props.dataSource}
customSlide={({ index, item, style, width }) => (
<View key={index} style={[style, styles.customSlide]}>
<Image source={{ uri: item }} style={styles.customImage} />
</View>
)}
/>
);
}
}
const styles = StyleSheet.create({
customImage: {
height: 180,
marginRight: 20,
marginLeft: 20,
borderWidth: 1,
borderRadius: 10,
marginTop: 8,
},
customSlide: {
backgroundColor: '#eee',
},
});
you can add this to your project and use it wherever you need it like this:
import Slider from '../component/slider';
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
images: [
'https://placeimg.com/640/480/nature',
'https://placeimg.com/640/480/tech',
'https://placeimg.com/640/480/animals',
'https://placeimg.com/640/480/tech',
],
}
render() {
return (
<View style={{flex: 1, backgroundColor: '#eee'}}>
<Slider dataSource={this.state.images} />
</View>
);
}
}
Related
Below is the basic code for Responsive layout using npm package(react-native-responsive-screen). This is working fine as expected in Class component. But, I want to change the below code to Functional component. I have almost changed everything. Initially no error when i load the app in portrait/landscape mode. Once i change it to landscape/portrait, it will come up with some error.
Here is the link of Original source. https://github.com/marudy/react-native-responsive-screen/blob/master/examples/responsive-screen-orientation-change/README.md
import React, { useEffect, useState } from 'react';
import { StyleSheet, Dimensions } from 'react-native';
import { Container, View, Button, Text} from "native-base";
import {widthPercentageToDP as wp,
heightPercentageToDP as hp,
listenOrientationChange as lor,
removeOrientationListener as rol } from 'react-native-responsive-screen';
const Responsive = () =>
{
useEffect( () =>
{
lor();
return () => rol()
},[])
const styles = StyleSheet.create({
container: { flex: 1, alignItems: 'center', justifyContent:'center' },
title: {
backgroundColor: 'gray',
height: hp('10%'),
width: wp('80%'),
alignItems: 'center',
justifyContent:'center',
marginVertical: wp('10%'),
},
myText: {
textAlign:'center',
color:'white',
fontSize: hp('5%') // End result looks like the provided UI mockup
},
buttonStyle:
{
height: hp('8%'), // 70% of height device screen
width: wp('30%'),
marginHorizontal: wp('10%'),
},
buttonContainer:
{
flexDirection:'row',
marginBottom: wp('10%'),
},
paraContainer:
{
width: wp('80%'),
},
paraText:
{
textAlign:'justify'
}
});
return (
<Container>
<View style={styles.container}>
<View style={styles.title}>
<Text style={styles.myText}>Screen title with 50% width</Text>
</View>
<View style={styles.buttonContainer}>
<Button success style={styles.buttonStyle}><Text>Button 1</Text></Button>
<Button success style={styles.buttonStyle}><Text>Button 2</Text></Button>
</View>
<View style={styles.paraContainer}>
<Text style={styles.paraText}>
As mentioned in "How to Develop Responsive UIs with React Native" article, this solution is
already in production apps and is tested with a set of Android, iOS emulators of different
screen
specs, in order to verify that we always have the same end result.
</Text>
</View>
</View>
</Container>
);
}
export default Responsive;
Thanks in Advance.
It is not due to your code, it is due to library limitation. Current version of library still does not support functional components.
There is an open issue and PR regarding that open
issue: https://github.com/marudy/react-native-responsive-screen/issues/82
PR: https://github.com/marudy/react-native-responsive-screen/pull/70
If you still want to continue with this library, just use the head of that PR in your package.json and it should work.
"react-native-responsive-screen": "marudy/react-native-responsive-screen#70/head",
Make sure to delete node_module and perform yarn or npm install
If I understand correctly -- making the outermost container as "flex: 1" should let the component span the whole screen.
However, the code I wrote is not working properly.
import React from 'react';
import { View, Text } from 'react-native';
export default function test() {
return (
<View style={{ flex: 1, borderColor: 'red', borderWidth: 5 }}>
<Text>test</Text>
</View>
);
}
The simulator screenshot is here
Can anyone please point out where I did wrong?
Thank a lot!
Where are you calling this component? Yes, the flex will expand, but it is dependent on that parent component container. It looks like your parent is the one restricting this component.
Ensure the parent is also flexing and filling the content. Here is some more details around flex layout: https://facebook.github.io/react-native/docs/flexbox
Change your code to import the Component as a class:
import React from 'react';
import { View, Text } from 'react-native';
export default test extends React.Component {
render() {
return (
<View style={{ flex: 1, borderColor: 'red', borderWidth: 5 }}>
<Text>test</Text>
</View>
);
}
}
I'm trying to detect when a user presses on a custom UI component I have written (it displays a video feed). I've tried using all the touchable components, and would ideally want to use the TouchableWithoutFeedback component, but none of them detect presses on my component. Additionally, when I select my component with the inspector, I get the error Expected to find at least one React renderer but I'm not sure how to set up my component correctly to have a renderer.
The native UI component:
public class DroneVideoFeedManager extends SimpleViewManager<DroneVideoFeed> {
#Override
public String getName() {
return "DroneLiveVideo";
}
#Override
public DroneVideoFeed createViewInstance(ThemedReactContext context) {
return new DroneVideoFeed(context, null);
}
}
My UI component Javascript wrapper is as follows:
import PropTypes from 'prop-types';
import {
requireNativeComponent,
ViewPropTypes,
} from 'react-native';
const iface = {
name: 'DroneLiveVideo',
propTypes: {
resizeMode: PropTypes.oneOf(['cover', 'contain', 'stretch']),
...ViewPropTypes, // include the default view properties
},
};
module.exports = requireNativeComponent('DroneLiveVideo', iface);
And my attempt to detect a press:
<TouchableWithoutFeedback
onPress={() => console.log('pressed!')}
>
<DroneLiveView
style={{
width: '100%',
height: '100%',
}}
/>
</TouchableWithoutFeedback>
This is the first time I have attempted to implement a native UI component in React Native, so apologies in advance if I am doing things incorrectly.
I found a solution, it's perhaps a little convoluted and not the best way of doing things but it works!
I changed my javascript wrapper to return a view with my native UI component, and another view above it (using absolute positioning). This view appears to handle touches and allows touchables to work with my component.
My changed UI component wrapper is as follows:
import React, {
Component,
} from 'react';
import {
requireNativeComponent,
View,
} from 'react-native';
class DroneVideo extends Component<{}> {
constructor(props) {
super(props);
}
render() {
return (
<View
{...this.props}
>
<View
style={{
width: '100%',
height: '100%',
position: 'absolute',
zIndex: 2,
}}
></View>
<DroneVideoNative
style={{
width: '100%',
height: '100%',
position: 'absolute',
zIndex: 1,
}}
/>
</View>
);
}
}
let DroneVideoNative = requireNativeComponent('DroneLiveVideo', DroneVideo);
export default DroneVideo;
I have a problem with React Native FlatList,
export default class PoolList extends Component {
constructor(props) {
super(props)
this.state = {
data: [
{key: 1, img: './resources/image1.png', txt: 'Text 1'},
{key: 2, img: './resources/image2.png', txt: 'Text 2'},
{key: 3, img: './resources/image3.png', txt: 'Text 3'}
]
}
}
render() {
return (
<View style={styles.view}>
<FlatList
data={this.state.data}
renderItem={({item}) =>
<View style={styles.flatListItem}>
<Image source={require(item.img)} />
<Text>{item.txt}</Text>
</View>
}
/>
</View>
);
}
}
I got a bug when run it
require() must have a single string literal argument
But when I change <Image source={require(item.img)} /> to <Image source={require('./resources/image1.png')} />, It works. Can someone explain to me why. I need to make a FlatList with Image dynamic, Thanks
It took me quite a while to figure out a workaround to this problem. Don't worry, require() must have a single string literal argument is a really common problem in the JavaScript community because require has a lot of issues with variables being passed in as the string argument.
This is the best workaround I could come up with.
So instead of using a flatlist, I decided to use a map. First off, you need to create constants for each of the images you want to dynamically import from a local directory. Then you need to create an array of objects so each object will be one of your image constants. Now, iterate through each entry using the map and generate your <Image> components. Finally, render the variable with all the components you just created.
To view the full code for the solution I wrote, visit the ExpoSnack I created.
https://snack.expo.io/HyNO-pLQG
SnackExpo also has an in-browser device simulator included.
To run this app on your physical device, you can download the Expo app and then scan the QR code provided by the ExpoSnack.
import React, {Component} from 'react';
import {View, Image, StyleSheet} from 'react-native';
const image1 = require('./resources/image1.png');
const image2 = require('./resources/image2.png');
const image3 = require('./resources/image3.png');
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
image: {
width: 200,
height: 200,
},
});
var dataArray = [
{data: image1},
{data: image2},
{data: image3},
];
var theReturnData = dataArray.map((item) => (
<View key={item}>
<Image
style={styles.image}
source={item.data}
/>
</View>
));
export default class App extends Component {
render() {
return (
<View style={styles.container}>
{theReturnData}
</View>
);
}
}
So there are two components sort of like this:
<View>
<Component1 />
<Component2 />
</View>
Both, Component1 & Component2 can be dragged and dropped within the View. By default, Component2 will render above the Component1 (since it is above in the stack). I want to make it so that whenever I press Component1 (for drag and drop) it dynamically comes infront of Component2 (Higher zIndex) and if I press Component1 and drag and drop, Component1 comes infront of Component2.
Anyone has any idea on how this can be done?
Edit 1:
I'm using zIndex, but for some reason it's working on iOS but not working on Android. Here's the basic code:
<View>
<View style={{position:'absolute',zIndex:2,backgroundColor:'red',width:500,height:500}}/>
<View style={{position:'absolute',zIndex:1,backgroundColor:'green',width:500,height:500,marginLeft:50}}/>
</View>
Setting dynamic zIndex for child components looks like the way to go. (zIndex on docs)
I would store the zIndexes of each child in the state. And I would wrap Component1 and Component2 with a touchable component if they are not already. When dragging & dropping starts, I'd update the zIndex stored in the state so that the required child would have higher zIndex.
Since I don't exactly know how you structured the components and their layouts, I am unable to provide a example code piece.
EDIT
Workaround for missing zIndex implementation on Android
I'd go something like this, if nothing else works:
import React from 'react';
import {
StyleSheet,
View,
} from 'react-native';
const style = StyleSheet.create({
wrapper: {
flex: 1,
position: 'relative',
},
child: {
position: 'absolute',
width: 500,
height: 500,
},
});
class MyComponent extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
reverseOrderOfChildren: false,
};
}
render() {
const firstChild = <View style={[style.child, {backgroundColor: 'red'}]} />
const secondChild = <View style={[style.child, {backgroundColor: 'green'}]} />
if (this.state.reverseOrderOfChildren) {
return (
<View style={style.wrapper}>
{secondChild}
{firstChild}
</View>
);
}
return (
<View style={style.wrapper}>
{firstChild}
{secondChild}
</View>
);
}
}