I built simple light box by Animated.View . on my light box I put Button to close light box .How can do that.I dont want to use package like react native router flux
class Baselightbox extends Component {
constructor(props) {
super(props);
this.state = {
opacity:new Animated.Value(0)
};
}
close(){ //here => how to close light box
Animated.timing(
this.state.opacity,{
duration:3000,
toValue:0
}).start()
}
renderlightbox(){
const {width=deviceWidth,height=deviceHeight/2,children,backgroundColor,Btitle}=this.props
return(<View style={{flex:1,justifyContent:'center'}}>
{children}
<Button title={Btitle} onPress={()=>{this.close()}} />
</View>)
}
componentWillMount(){
Animated.timing(
this.state.opacity,{
duration:3000,
toValue:1
}).start()
}
render() {
const { height : deviceHeight , width : deviceWidth} = Dimensions.get('window');
const {width=deviceWidth,height=deviceHeight/2,children,backgroundColor,Btitle}=this.props
return (
<Animated.View style={{opacity:this.state.opacity,borderRadius: 10,width,height,backgroundColor,padding:30}}>
{this.renderlightbox()}
</Animated.View>
);
}
}
My Code
Take a look at my codes :)
Related
My application scenario is like, let say you have three components:
class ComponentOne extends Component {
render() {
return (
<View>
<Text>Component One</Text>
<Button
title='Go To Component Two'
onPress={() => this.props.navigation.navigate('two')}/>
</View>
);
}
}
class ComponentTwo extends Component {
render() {
return (
<View>
<Text>Component Two</Text>
<Button
title='Go To Component Three'
onPress={() => this.props.navigation.navigate('three')}/>
</View>
);
}
}
class ComponentThree extends Component {
render() {
return (
<View>
<Text>Component Three</Text>
<Button
title='Go To Component One'
onPress={() => this.props.navigation.navigate('one')}/>
</View>
);
}
}
export default createStackNavigator({one: ComponentOne,two: ComponentTwo,three: ComponentThree});
Now when I load the app the ComponentOne will be loaded, inside the ComponentOne when I click on the button Go To Component Two it will navigate me to the ComponentTwo, inside ComponentTwo when I click on the button Go To Component Three it will navigate me to the ComponentThree and so on. Now let say I am in ComponentTwo and on the same time I close the application in the phone and I open the app switcher and clean all the running apps and load the same app again, so, it will be again loaded with ComponentOne.
My question is how to program the react navigation to continue from the same component where last time I left, even after cleaning the app from a background (cleaning all apps in app switcher)?
Is there any builtin way in react navigation to do this? Can anyone tell? Examples will be more appreciated. Thanks!
All Navigators have onNavigationStateChange where you can handle the navigation state changing. Example code:
import React from 'react';
import { AsyncStorage } from 'react-native';
import { createStackNavigator, NavigationActions } from 'react-navigation';
const Navigator = createStackNavigator({
ComponentOne: {
screen: ComponentOne,
},
ComponentTwo: {
screen: ComponentTwo,
},
ComponentThree: {
screen: ComponentThree,
},
}, {
initialRouteName: 'ComponentOne',
});
class App extends Component {
constructor(props) {
this.navigator = React.createRef();
}
componentDidMount() {
try {
// Retrieve the last route
const value = AsyncStorage.getItem('lastNavigationRoute').then((result) => {
if (result) {
this.navigator.current.dispatch(NavigationActions.navigate({
routeName: result,
}));
}
});
} catch (e) {
// handle the error
}
}
handleStateChange = (previousState, nextState) => {
// Here we get the Navigate action type only
const navigateAction = NavigationActions.navigate({ routeName: 'dummyRoute' });
if (action.type === navigateAction.type) {
try {
// Saving the last route
AsyncStorage.setItem('lastNavigationRoute', nextState.routeName);
} catch (e) {
// handle the error
}
}
}
render() {
// You could also set a state with loader to handle loading from AsyncStorage
return (
<Navigator onNavigationStateChange={this.handleStateChange} ref={this.navigator} />
);
}
}
How it works:
On every navigation state changing you also save the last routeName
from Navigate action
When component did mount, you check for saved
route in AsyncStorage
If there is a route, you dispatch the navigate action (it's possible to implement replace action as well)
Hope it helps.
i dont think that there is a solution directly using react-navigation.
What i think you could do is to save a value of the current screen to the storage of the phone and then use this value on app start to detect which screen to show
Am trying to animate an image to shrink when the onscreen keyboard is called (see code below). Got it working on IOS but not on Android :(
I have searched the web for solutions, but so far nothing works. Any suggestions?
Thanks in advance
constructor(props) {
super(props);
this.imageSize = new Animated.Value(imageSizeNormal);
}
componentWillMount() {
this.keyboardWillShowSub = Keyboard.addListener('keyboardWillShow', this.keyboardWillShow);
this.keyboardWillHideSub = Keyboard.addListener('keyboardWillHide', this.keyboardWillHide);
}
componentWillUnmount() {
this.keyboardWillShowSub.remove();
this.keyboardWillHideSub.remove();
}
keyboardWillShow = (event) => {
Animated.timing(this.imageSize, {
toValue: imageSizeSmall
}).start();
};
keyboardWillHide = (event) => {
Animated.timing(this.imageSize, {
toValue: imageSize
}).start();
};
render() {
return (
<Animated.Image
source={require('../../assets/circle.png')}
resizeMode="contain"
style={[styles.logo, { height: this.imageSize, width: this.imageSize}]}
/>
)
}
const imageSizeNormal = Dimensions.get("window").width/2;
const imageSizeSmall = Dimensions.get("window").width/4;
Here's how I solved it.
First thing I did was change the keywords "keyboardWill..." to "keyboardDid...""
Second, I added the following to AndroidManifest.xml
android:fitsSystemWindows="true"
android:windowSoftInputMode="adjustResize"
Sources:
windowSoftInputMode="adjustResize" not working with translucent action/navbar
https://medium.freecodecamp.org/how-to-make-your-react-native-app-respond-gracefully-when-the-keyboard-pops-up-7442c1535580
I have a react native TextInput with numeric keyboard, and it is working fine, except that the keyboard shows up again after the submit button has been clicked and it navigates to the next page (ShouldNotHaveKeyboardScreen). The next page has no text input and the keyboard should never show on that page. I want to make sure the keyboard doesn't show on the next screen, but I can't figure out how to do it. I attempted to dismiss the keyboard on submitting the textInput, but that doesn't work. I've also tried to dismiss it on the next screen as it loads, but that does't fully work either. The best I can do is to hide it after it pops up, but that is not ideal, I want it to be never shown.
I am using an android device (Android v.6.0.1) with react-native v0.48.3.
Here is the code, I've tried to remove any irrelevant parts.
// The screen that should not have keyboard
import { Keyboard } from 'react-native';
class ShouldNotHaveKeyboardScreen extends Component {
componentDidMount() {
Keyboard.dismiss(); // < that doesn't seem to work
Keyboard.addListener('keyboardDidShow', this._keyboardDidShow);
}
componentWillUnmount() {
Keyboard.removeListener('keyboardDidShow', this._keyboardDidShow);
}
_keyboardDidShow() {
console.warn("keyboard did show");
Keyboard.dismiss(); // < this works, but the keyboard pops up first
}
// other stuff
}
// The screen with numeric text input
class TextInputScreen extends Component {
componentDidMount() {
Keyboard.addListener('keyboardDidHide', this._keyboardDidHide);
}
componentWillUnmount() {
Keyboard.removeListener('keyboardDidHide', this._keyboardDidHide);
}
_keyboardDidHide() {
console.warn("keyboard did hide oh yeah");
Keyboard.dismiss(); // This doesn't help, the event happens but the next screen still shows keyboard
}
handleSendReadCommand(value) {
// some stuff
this.props.navigation.navigate('ShouldNotHaveKeyboardScreen');
}
}
render() {
return (
<ScrollView style={styles.mainContainer}>
<View style={styles.contentContainer}>
<View style={styles.Container}>
<View>
<Text style={styles.Title}>Text here</Text>
<ColoredTextInput inFocus={true}
value={this.props.setting_id}
returnKey={"search"}
onChangeText={(text) => { someAction(text)}}
onSubmitEditing={(event) => {
Keyboard.dismiss(); // This doesn't help
this.handleSendReadCommand(event.nativeEvent.text)}}
/>
</View>
</View>
</View>
</ScrollView>
);
}
}
// numeric text input component
export default class ColoredTextInput extends Component {
constructor(props) {
super(props);
this.state = {style: props.inFocus ? styles.text_input_in_focus : styles.text_input_not_focused};
this.onFocus = () => this.setState({ style: styles.text_input_in_focus });
this.onBlur = () => this.setState({ style: styles.text_input_not_focused });
}
static propTypes = {
inFocus: PropTypes.bool.isRequired,
onChangeText: PropTypes.func,
onSubmitEditing: PropTypes.func,
returnKey: PropTypes.string,
};
render() {
let return_key = 'done';
if (this.props.returnKey) {
return_key = this.props.returnKey;
}
return (
<TextInput
style={[styles.text_input, this.state.style]}
autoFocus={this.props.inFocus}
returnKeyType={return_key}
keyboardType="numeric"
underlineColorAndroid="transparent"
onBlur={() => this.onBlur()}
onFocus={() => this.onFocus()}
value={this.props.value}
onChangeText={ this.props.onChangeText }
onSubmitEditing={ this.props.onSubmitEditing }
/>
);
}
}
How can I hide the keyboard?
I would like to have button change its color when pressed. I tryed checking out other similar topics but I couldn't find a solution. The code renders and the initial button color is red, but when I press it, nothing happens.
export default class someProgram extends Component {
render() {
var buttonColor = "red";
function changeButtonColor(){
if(this.buttonColor === "red"){
this.buttonColor = "green";
}
else{
this.buttonColor = "red";
}
}
return (
<View style={styles.container}>
<Button
title="Press me!"
color={buttonColor}
onPress={() => {changeButtonColor(buttonColor)}}
/>
</View>
);
}
}
You should keep track of the color in the component state. As a side, make sure to understand what the keyword this really means. Do a console.log(this) and see it for yourself.
Anyway, you can
(1) set the initial state in the constructor;
(2) access value from the state using this.state.someProp
then (3) adjust the state later using this.setState({ someProp: someValue }).
1) Initial State
constructor(props) {
super(props);
this.state = {
buttonColor: 'red'; // default button color goes here
};
}
2) Accessing the State &
3) Setting New State
onButtonPress = () => {
this.setState({ buttonColor: 'someNewColor' });
}
render() {
// ...
return (
{/* ... */}
<Button
color={this.state.buttonColor}
onPress={onButtonPress}
/>
)
Note some parts of the code were omitted to focus on the question at hand.
I'm trying to get navigating working with react-native. I am testing it with 2 pages (HomePage & OtherPage) and want HomePage to be able to nav to OtherPage when I submit some text.
My basic navigator index.android.js file...
class MyApp extends Component {
_renderScene = function(route, nav) {
switch (route.index) {
case 'HomePage':
console.log('homepage nav')
return <HomePage navigator={nav} />
case 'OtherPage':
console.log('otherpagenav')
return <OtherPage navigator={nav} />
}
}
render() {
return (
<Navigator
initialRoute={{ title: 'My Initial Scene', index: 'HomePage' }}
renderScene={ (route, nav) => { return this._renderScene(route, nav) } }
/>
)
}
}
Both pages HomePage and OtherPage work if I set them manually via the index and initialRoute.
initialRoute={{ title: 'My Initial Scene', index: 'HomePage' }}
or
initialRoute={{ title: 'My Initial Scene', index: 'OtherPage' }}
My HomePage.js file which is loaded fine, looks like...
class HomePage extends Component {
constructor(props) {
super(props);
}
_onSubmit() {
console.log( 'submit2', this);
this.props.navigator.push({
title: "Other Page",
index: 'OtherPage',
component: OtherPage,
passProps: { testprop: 'someuser'},
});
}
render() {
return (
<View>
<Text>Current Scene: {this.props.title}</Text>
<TextInput
onChangeText = {( keywords ) => this.setState({ keywords })}
defaultValue = 'Type a keyword'
onSubmitEditing = { this._onSubmit.bind( this ) }
/>
</View>
)
}
}
My Test OtherPage is just
class OtherPage extends Component {
constructor( props ) {
super( props );
}
componentDidMount() {
console.log( 'otherpage component mounted');
}
render() {
return (
<View><Text>Other Page</Text>
</View>
);
}
}
When I enter some text and submit. I see the submit console.log from _onSubmit() So I know the navigator is getting called ok.
I also see 'otherpage component mounted'.
So everything looks ok log wise, but I don't see the scene/page updated, all I see is the updated console.logs.
Is there something I need to do to force it to update the scene, or shouldn't it happen automatically with the navigator push ? (I'm also a little unsure of the need for navigator component, as I've seen it in some example, but not really referenced anywhere).
Looks like there was something odd with the avd. I ended up upgrading react-native to 0.39.2 (which I don't think made a difference, but including for completeness). Then I deleted the avd, created a mew one (target name Android 6.0 Platform 6.0 API 23 Intel Atom x86_64) selected delete all user data, and then it seems to work.
Wish I knew specifically why, so if anyone has a better answer, I will gladly accept.