react native changing Animated.Image source without blinking - react-native

when its changed source of any image in component there is blinking occurs which I try to avoid.
To do so I searched and decided to use ref(direct manipulation)
but it doenst change anything, so I use traditional way, changing url property in the state, it works but blink occurs.
Changing image source, fired when image started to move;("onPanResponderStart") function. here is code;
onPanResponderStart:(e, gesture)=>{
//not change image!
// this.refs['refTabure'].setNativeProps({
// source: require('../newImage.png')
// });
//it works, but blink occurs
this.setState({tabureSagImageUrl:require('../newImage.png')})
},
...
return (
<View style={styles.TabureStyle}>
<Animated.Image ref="refTabure" style={[panStyle, styles[this.props.Name], {opacity:this.state.opacity}]}
{...this.panResponder.panHandlers}
source={this.state.tabureSagImageUrl}>
</Animated.Image>
</View>
);
how can I edit the source of image without rerendering component that cause blinking ?

Related

React-native-video not change video when change source

I use react-native-video to render a video player for my app.
I try to change the source of the video. This is my code run well.
<Video
source={{uri: _getVideo().video_url}}
style={Styles.backgroundVideo}
autoplay={true}
controls={false}
disableFocus={true}
resizeMode="cover"
/>;
But I change 'controls={true}'. It don't render new video, just render audio. And still show old video.
_getVideo().video_url
This function just return source video. I'm sure element also changes source but not re-render new video.
Is there any solution to resolve it?
You are doing it the wrong way, though it works.
But let me tell you what's happening here,
source={{uri: _getVideo().video_url}}
this line executes every time the render method is executed, and the render method is called after setState, props changes, and other events.
So your _getVideo() method will be called any number of times though it is not required.
Hence I suggest you initialize one state variable for URL. call your _getVideo() somewhere you want. maybe on componentDidMount for first run and afterward button click or anything else you want but set this URL into that state with setState in _getVideo method.
so desired thing will be like this,
<Video
key={this.state.videoComponentKey}
source={{uri: this.state.video_url}}
style={Styles.backgroundVideo}
autoplay={true}
controls={false}
disableFocus={true}
resizeMode="cover"
/>;
Now if you have noticed I have added one more prop key, this will solve your old video problem. whenever URL is changed change something in the key. so I have taken one state and passed it to this prop. now you can initialize it with 0 and next time just increment it using setState.

How to add enum image source to React-native-circle-button?

I am trying to add a custom image source to the attribute iconButtonCenter in the React Native library named react-native-circle-button.
https://github.com/dwicao/react-native-circle-button
According to the documentation, iconButtonCenter is of type enum, so I imported the icon and then passed it in directly where I create my CircleButton object. It does not yell as if it is a number or string, yet I still am not 100% sure it is technically of type enum. I know for a fact it is finding the image in the right path. I also know that it is doing something, because the default image is no longer observable on the app, it just no longer has an icon. I am not getting any compilation errors or warning, yet I still do not see the icon appear over the button as it should. How do I fix this?
Here is the render within my component that allows circle button's to be draggable. I also went ahead and put my import at the top so you can see how this was stored.
import letterA from '../assets/letters/alpha-a.svg';
render() {
let { pan } = this.state;
let [translateX, translateY] = [pan.x, pan.y];
let moveableStyle = {transform: [{translateX}, {translateY}]};
const panStyle = {
transform: this.state.pan.getTranslateTransform()
}
return (
<Animated.View
{...this._panResponder.panHandlers}
style={[moveableStyle, panStyle]}>
<CircleButton iconButtonCenter={letterA} /> <--- Here is the image source reference.
</Animated.View>
);
}
The CircleButton component should successfully have the image fed to it and remain centered over the button even when dragged along the string.
Problem was the picture format was an .svg, converting the icons to .png worked like a charm!

react-native - TouchableHighlight: Remove highlighting after onPress?

I am developing a simple react-native app and am encountering an issue on TouchableHighlight:
When pressing the TouchableHighlight, a new screen is displayed (using StackNavigator from react-navigation). After pressing the back-button and returning to the original screen, the TouchableHighlight still has a black background-color - meaning, that it is still highlighted.
My questions are:
Is there a way to manually deactivate the highlighting of a TouchableHighlight-component? That way I could disable the highlighting after onPress has run.
What could be possible reasons to why the TouchableHighlight stays highlighted? I am using it on other parts of my app without navigation, and I could imagine that it has to do with that.
The TouchableHighlight exists within a FlatList. The renderItems-method looks like the following:
let handlePress = () => {
this.props.navigation.navigate('DetailsScreen');
};
return <TouchableHighlight
onPress={handlePress}>
<Text>Some Text</Text>
</TouchableHighlight>;
If you need/want any further information, please let me know. I've tested the code on android, using the Genymotion-emulator with Marshmallow.
Versions are:
node -v: 8.9.4
npm -v: 5.6.0
react-native-cli: 2.0.1
react-native: 0.54.2
react-navigation: 1.5.2
Build environment: Windows 10 64-bit
At this point, I'm quite certain that the error is somewhere in my code, as TouchableHighlight works correctly on other parts of my app, and it propably has to do with the navigation-call, but I was unable to pinpoint, why exactly. I've made sure that there are no exceptions or anything like that in my app, and that the onPress-method therefore finishes successfully.
You can replace Touchable Highlight with Touchable opacity and simply set activeOpactity prop with value 1. It will not highlight the press.
<TouchableOpacity activeOpacity={1}>....</TouchableOpacity>
After using the tip from #Kartiikeya and exchanging TouchableHighlight with TouchableOpacity and back to TouchableHighlight, it now works as expected:
Now, after onPress has been executed, the button (be it a TouchableOpacity or a TouchableHighlight) looses its effect.
I am not sure, why it works now. The obvious reason would be, that a recompilation of the source code fixed errors - but I recompiled it for writing the original question multiple times before, so that that cannot be an option. Other users I would suggest to clear any cache possible, and especially do the following steps:
Close and reopen the android emulator / restart your testing device
Restart the build PC
Recompile all source code
Check in your console for errors and/or exceptions (obviously)
Replace TouchableHighlight with TouchableOpacity, recompile, check if the error still exists - and if not, reexchange TouchableOpacity to TouchableHighlight
You can replace Touchable Highlight with Touchable opacity. It won't highlight the press.
return <TouchableOpacity
onPress={handlePress}>
<Text>Some Text</Text>
</TouchableOpacity >;
For me, i needed to disable the highlight effect after onLongPress has been fired. You can simply change the key of the touchable using a re-render when you want to remove it.
Here's an example:
<TouchableHighLight
onPress={this.pressRow}
style={styles.outerContainer}
onLongPress={() => this.setState({ onLongPressed: true })}
onPressOut={() => this.setState({ onLongPressed: false })}
key={`long-pressed-${this.state.onLongPressed ? 'yes' : 'no'}`}>
<View style={styles.innerContainer}>
{rowText}
{rowIcon}
</View>
</TouchableHighLight>
Following Leonardo Lusoli's answer, there one thing you should also add is
useEffect(() => {
if(isLongPressed){
setIsLongPressed(false)
}
}, [isLongPressed])
This step is necessary because
when the first onLongPress event is fired it will set isLongPressed to true and thus changing the key the component is re-rendered and is identifies as a new component and previour event listners are discareded so the onPressOut will not be fired. So
when isLongPressed is set to true the component re-renders and then immediatietly we set it's value to false and thus we get the expected behaviour. Otherwise we will get the unexpected behaviour followed by one expected behaviour.

React native detect screen rotation

I'm using onLayout to detect screen orientation and it's working fine inside my root view, but when I implemented inside the drawer it didn't work, any reason why this happens ?
code :
import Drawer from 'react-native-drawer'
...
onLayout(e) {
console.log('onLayout');
}
<Drawer onLayout={this.onLayout}
It didn't log any thing when orientation changed!
This is because the Drawer component doesn't take onLayout as a prop. You can see in the source code that the rendered View does use onLayout, but it's not pulling from something like this.props.onLayout.
I'm not exactly sure what you're looking to do, but maybe this issue will help you. As it shows, you can pass a function into openDrawerOffset instead of an integer or a ratio in order to be a little more dynamic with how you set your offset:
openDrawerOffset={(viewport) => {
if (viewport.width < 400) {
return viewport.width * 0.1;
}
return viewport.width - 400;
}}
You might also benefit from the Event handlers that react-native-drawer has to offer.

TouchableHighlight and TouchableOpacity get highlighted on render()

I experience a behaviour where TouchableHighlight and TouchableOpacity reacts visually upon render (onPress is not being called).
One thing is that it looks just a little strange, when I enter the page and my button make a small "blink". This is strange but tolerable. The more frustrating part is that if I alter state for the parent component and thus invoke a re-render(), the button will "blink" again, making all buttons blink whenever I alter state.
Pushing the buttons alters page state, and thus pushing a button makes both buttons "blink".
I use react-redux, but this should not affect this behaviour.
The code below is just for illustration.
render()
{
return(
<View>
<ToucableHightlight> //Click here changes state
<Content/>
</ToucableHightlight>
<ToucableHightlight> //Click here changes state
<Content/>
</ToucableHightlight>
<View>
);
}
Add activeOpacity in TouchableOpacity and it will force to not blink.
<TouchableOpacity style={styles.opecity} activeOpacity={1}>
I solved the problem. Earlier during my render function i defined the "Content"-components, resulting in new (but alike) components being defined during each update. Placing the definitions of "Content" outside of the render function fixed it, so that the components no longer flashes when the page is re-rendered.
This explains why my component was rendered as a new component upon each render in the parent component, but it does not explain why a TouchableHighlight blinks during its initial render.
Buttons blinking during initial render is acceptable to me - buttons blinking upon any state-change is not.
So I am sufficiently happy now.
Not sure if it's because I'm running a later version, but I found this blinking behavior happens only on the first click.
My solution was putting the code that triggers rerendering in a setTimeout
<TouchableOpacity
onPress={function() {
setTimeout(function() {
_this.setState({myState: 'someValue'})
});
}}
>