Re-render React Swiper Component - react-native

I want to play a audio on card, when click on the play icon, it plays, i update player state to playing and want to change play icon to pause icon. But cant re-render the card. I have read https://github.com/alexbrillant/react-native-deck-swiper/issues/153 but no solution, how to solve this ?
setPlay2(index, sound, stopper = false) {
....
this.setState({
playing: 'playing',
});
.....
}
const {
playing
} = this.state;
....
<Swiper
ref={(swiper) => {
this.swiper = swiper;
}}
cards={data}
cardIndex={cardIndex}
renderCard={card => (
<View style={{ flex: 1 }}>
<TouchableOpacity onPress={() => this.setPlay2()}>
{
playing === 'playing' ? (
<Image source={require('#images/BasicAppMenu/pause.png')} style={{ height: 32, width: 32 }} />
) : (
<Image source= {require('#images/BasicAppMenu/play.png')} style={{ height: 32, width: 32
}} />
)
}
</TouchableOpacity>
</View>
)}
/>

Just to check playing within the <TouchableOpacity> element - is this this.state.playing ? You've not included all the code.
If not, this may work?
<TouchableOpacity onPress={() => this.setPlay2()}>
{
this.state.playing === 'playing' ? (
<Image source={require('#images/BasicAppMenu/pause.png')} style={{ height: 32, width:
32 }} />
) : (
<Image source= {require('#images/BasicAppMenu/play.png')} style={{ height: 32,
width: 32
}} />
)
}
</TouchableOpacity>

Related

Auto Focus Property is not working in Text Input Component on React Native

I am making a Search Bar and I want they keyboard to open up once the Search button has been clicked however the autoFocus property of the TextInput is not working. What am I doing wrong?
Here's the code:
const SearchBar = () => {
return (
<View style={{ flex: 1 }}>
<TextInput placeholder="Search"
style={{ width: Dimensions.get('screen').width, height: 50, borderWidth: 1,
borderRadius: 20 }}
autoFocus={true}
/>
</View>
)
}
const Search = () => {
return (
<TouchableWithoutFeedback onPress={()=>Keyboard.dismiss()} >
<SearchBar />
</TouchableWithoutFeedback>
)
}
umm, ideally autoFocus should work on mounting of this comp.
If its not, workaround would be explicitly adding a ref and focusing it
class ABC extends .. {
constructor(props){
...
this.textInput = React.createRef();
}
componentDidMount(){
this.textInput.current.focus();
}
SearchBar = () => {
return (
<View style={{ flex: 1 }}>
<TextInput placeholder="Search"
style={{ width: Dimensions.get('screen').width, height: 50, borderWidth: 1,
borderRadius: 20 }}
autoFocus={true}
ref={this.textInput}
/>
</View>
)
}
}

Open a video player in react native

I'm working on an app where I need to display a player with an embed youtube video. I have retrieve the data of a youtube playlist, and put them in a TouchableHighlight. I want now to display a player in a WebView, but just on top of my list. So when I'm clicking on a video, the list go down and a WebView take the place ? Is it possible ? Here is the code :
Fetching data from YTApi
_fetchPlaylist(){
if(this.state.selectedIndex === 0) {
return(
fetch(`https://www.googleapis.com/youtube/v3/playlistItems?part=snippet,contentDetails&maxResults=${results}&playlistId=PLSlVQ0kIy6qx-f5O3J3GwIEOO5Y52z43-&key=${apiKey}`)
.then(res => res.json())
.then(res => {
const videoId = []
res.items.forEach(item => {
videoId.push(item)
})
this.setState({
data:videoId
})
})
.catch(error => {
console.error(error)
})
)
}
}
displayWebView
displayVideo(videoId){
if(this.state.selectedIndex == 0){
return(
<View style = {{height:300}}>
<WebView
style={{flex:1}}
javaScriptEnabled={true}
source={{uri: `https://www.youtube.com/embed?v=x57qZ8Ym51s&list=${videoId}`}}
/>
</View>
)
} else{
return <View></View>
}
}
render
<View style = {styles.containerPlaylist}>
<ScrollView>
<View style = {styles.body}>
{
this.state.data.map((item,i) =>
<TouchableHighlight
key = {item.id.videoId}
onPress = {()=> this.displayVideo(item.id.videoID)}>
<View style = {styles.vids}>
<Image
source = {{uri: item.snippet.thumbnails.medium.url}}
style = {{width: 120, height: 90,marginVertical:30, flexDirection:'column', alignSelf:'flex-start', backgroundColor:'#fff', resizeMode:'contain'}}
/>
<Text style = {styles.vidText}>{item.snippet.title}</Text>
</View>
</TouchableHighlight>
)}
</View>
</ScrollView>
</View>
Thanks
You need to keep webview in your layout and then need to manage two state,
to show and hide webview/video
to change the url of webview/video
Initialize the state like this along with your other state:
this.state = {
showVideo: false,
videoUrl: "default youtube url or empty string"
}
then create your layout like this and adjust your styling as per your need:
<View style={styles.containerPlaylist}>
<ScrollView>
{this.state.showVideo &&
<View style={{ height: 300 }}>
<WebView
style={{ flex: 1 }}
javaScriptEnabled={true}
source={{ uri: this.state.videoUrl }}
/>
</View>
}
<View style={styles.body}>
{
this.state.data.map((item, i) =>
<TouchableHighlight
key={item.id.videoId}
onPress={() => this.displayVideo(item.id.videoID)}>
<View style={styles.vids}>
<Image
source={{ uri: item.snippet.thumbnails.medium.url }}
style={{ width: 120, height: 90, marginVertical: 30, flexDirection: 'column', alignSelf: 'flex-start', backgroundColor: '#fff', resizeMode: 'contain' }}
/>
<Text style={styles.vidText}>{item.snippet.title}</Text>
</View>
</TouchableHighlight>
)}
</View>
</ScrollView>
</View>
and change your function something like this to display video which has been clicked:
displayVideo(videoId) {
this.setState({
videoUrl: `https://www.youtube.com/embed?v=x57qZ8Ym51s&list=${videoId}`
showVideo: true
});
}

React-Native-Swiper images Overflow ONLY ON ANDROID

I have a problem with react-native-swiper on Android ONLY. The same code works for iOS!
Below is an image of what is happening:
The area is blue is supposed to be a square and all images should be within it. Something like this (I only render 1 image here):
This is what my code looks like:
renderSwiper = () => {
const images = this.props.data.item[1].images;
let swiperImages = images.map((image, index) => {
let priority = FastImage.priority.normal;
if (index === 0)
priority = FastImage.priority.high;
return (
<TouchableWithoutFeedback key={index} onPress={this.routeToListingDetails} >
<FastImage
style={styles.imageStyle}
source={{uri: image, priority: priority}}
/>
</TouchableWithoutFeedback>
)
})
return (
<View style={{ aspectRatio: 1, width: '100%'}}>
<Swiper
loop={false}
paginationStyle={styles.swiperPaginationStyle}
>
{swiperImages}
</Swiper>
</View>
);
}
render(){
return (
<View style={styles.container} >
<View style={{ borderColor: 'blue', borderWidth: 2 }}>
{this.renderSwiper()}
</View>
</View>
)
}
const styles = StyleSheet.create({
container:{
width:'50%',
alignItems:'center',
marginBottom:'4%',
padding:'2%',
},
imageStyle:{
resizeMode: "cover",
width: "100%",
aspectRatio:1
}
})

How to use checkboxes in react native for both android and IOS?

I have a modal with diffrent tabs in my app in which user can filter the search result with categories in the modal . right now it is working but I simply put an event on a <TEXT> , I need some visual clue like checkbox for my options
{this.state.currentTab === 1 && (
<View>
<Text onPress={(text) => this.setGender(true)}>male</Text>
<Text onPress={(text) => this.setGender(false)}>female</Text>
</View>
)}
How Can I use checkbox instead of <TEXT> to use both in android and IOS?
You can use this library for the checkbox
" react-native-circle-checkbox "
import CircleCheckBox, {LABEL_POSITION} from 'react-native-circle-checkbox';
{this.state.currentTab === 1 && (
<View>
<CircleCheckBox
checked={true}
onToggle={(text) => this.setGender(true)}
labelPosition={LABEL_POSITION.RIGHT}
label="MALE"
/>
<CircleCheckBox
checked={true}
onToggle={(text) => this.setGender(false)}
labelPosition={LABEL_POSITION.RIGHT}
label="FEMALE"
/>
</View>
)}
Example: https://snack.expo.io/#msbot01/intrigued-marshmallows
Use This Component which I manually created. It renders same radio button on both platforms
const RenderRadio = (props) => {
const {
value, onChange, selectedValue
} = props;
const checked = value === selectedValue;
return (
<TouchableOpacity
style={{ flexDirection: 'row' }}
onPress={() => onChange(value)}
>
<View
style={{
width: 20,
height: 20,
borderRadius: 10,
borderWidth: 2,
borderColor: '#002451',
justifyContent: 'center',
alignItems: 'center',
}}
>
<View
style={{
width: 10,
height: 10,
borderRadius: 5,
backgroundColor: checked ? '#002451' : 'white',
}}
/>
</View>
<Text style={{ fontSize: 15, marginLeft: 10 }}>{value}</Text>
</TouchableOpacity>
);
};
use it as
<RenderRadio onChange={this.setSelectedValue} selectedValue={selectedValue} value={value}/>
and set Your selected value as
setSelectedValue = (value) => {
this.setState(selectedValue : value)
}
You can use native-base library, that has more components which you can use for Search filters and this is more reliable, you can set it checked
using checked prop, that is boolean, like this :
import {
Icon,
CheckBox,
Spinner
} from "native-base";
<TouchableOpacity onPress={(text) => this.setGender(true)} >
<CheckBox checked ={tru}
onPress={(text) => this.setGender(true)} />
</TouchableOpacity>

Aligning button element with image element

is there a way to arrange this layout so that the image is on the left, and the button is on the right?
Right now, it just displays with the image at the top left, and the button that spans the whole width of the screen right below.
Thanks!
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Welcome',
};
render() {
const { navigate } = this.props.navigation;
return (
<View>
<Text>
Hello, Chat App!
</Text>
<Image
style={{width: 50, height: 50}}
source={getFunction(1)}
/>
<Button
style={{width: 50, height: 50}}
onPress={ () => navigate('Chat', { user: 'Abe', avatar: getFunction(1) })}
title = "Chat with Abe"
/>
<Image
style={{width: 50, height: 50}}
source={getFunction(2)}
/>
<Button
onPress={ () => navigate('Chat', { user: 'Jack', avatar: getFunction(2) })}
title = "Chat with Jack"
/>
<Image
style={{width: 50, height: 50}}
source={getFunction(3)}
/>
<Button
onPress={ () => navigate('Chat', { user: 'Kate', avatar: getFunction(3) })}
title = "Chat with Kate"
/>
);
}
}
You can try this:
The below code snippet is for alignment of one image and one button.
<View style={{ flex: 1, flex-direction: 'row', justifyContent: 'space-between' }}>
<View style={{ margin: 15 }} >
<Image style={{width: 50, height: 50}} source={getFunction(1)} />
</View>
<View style={{ margin: 15 }} >
<Button style={{width: 50, height: 50} onPress={ () => navigate('Chat', {
user: 'Abe', avatar: getFunction(1) })} title = "Chat with Abe" />
</View>
</View>
Cheers :)