Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 4 years ago.
Improve this question
What is the best module out there right now for image viewing? I wanted to find something like https://github.com/oblador/react-native-lightbox
which has swipe to dismiss features and such. But this module seems to be out of date. Anyone here use anything similar that works with latest version of React Native?
Something I can use to view images, pinch to zoom, swipe to dismiss are kinda essential for my app.
First you must know about routerFlux . then go to api and read the LightBox components...
so here is the simple codes that you make a boxlight:
import React from 'react';
import { View , Text } from 'react-native';
import { Router , Scene , Lightbox} from 'react-native-router-flux';
// Components
import ButtonPage from "./components/ButtonPage";
import LoginLightbox from "./components/lightbox/LoginLightbox";
class loginLightbox extends React.Component {
render() {
return (
<View style={{ flex : 1 , justifyContent: 'center' , alignItems: 'center'}}>
<Text>lightBox</Text>
</View>
)
}
}
export default class App extends React.Component {
render() {
return (
<Router>
<Lightbox>
<Scene key="root">
<Scene key="button" component={ButtonPage } title="ButtonPage " initial/>
</Scene>
<Scene key="loginLightbox" component={loginLightbox} />
</Lightbox>
</Router>
)
}
}
and this is the ButtonPage:
import React from 'react';
import { Container , Button } from 'native-base';
import { Actions } from 'react-native-router-flux';
import { form } from './../assets/styles';
export default class ButtonPage extends React.Component {
render() {
return (
<Container>
<Button full style={form.submitButton} onPress={() => Actions.loginLightbox()}>
<Text style={form.submitText}>ورود</Text>
</Button>
</Container>
)
}
}
now lets make tow class BaseLightBox:
import React from 'react';
import { Animated , Dimensions } from 'react-native';
import {View, Button, Text, Icon} from 'native-base';
import EStyleSheet from 'react-native-extended-stylesheet';
import { Actions } from 'react-native-router-flux';
const { height : deviceHeight , width : deviceWidth} = Dimensions.get('window');
export default class BaseLightbox extends React.Component {
constructor(props) {
super(props);
this.state = {
opacity : new Animated.Value(0)
}
}
componentWillMount() {
Animated.timing(this.state.opacity,{
toValue : 1,
duration : 200
}).start();
}
close() {
Animated.timing(this.state.opacity,{
toValue : 0,
duration : 200
}).start(Actions.pop);
}
_renderLightbox() {
const { children , verticalPercent = 1 , horizontalPercent = 1 } = this.props;
const width = verticalPercent ? deviceWidth * verticalPercent : deviceWidth;
const height = horizontalPercent ? deviceHeight * horizontalPercent : deviceHeight;
return (
<View style={{ width , height, justifyContent: 'center' , alignItems: 'center' , backgroundColor : 'white' , borderRadius : 4}}>
{children}
<Button transparent style={{ position: 'absolute', top : 0 , left : 0}} onPress={() => this.close() }>
<Icon name='md-close-circle' style={{ fontSize : 30 , color : '#34495e'}}/>
</Button>
</View>
)
}
render() {
return (
<Animated.View style={[styles.container , { opacity : this.state.opacity }]}>
{this._renderLightbox()}
</Animated.View>
)
}
}
const styles = EStyleSheet.create({
container : {
backgroundColor: 'rgba(52,52,52,.5)',
position: 'absolute',
top : 0 ,
bottom : 0,
left : 0,
right : 0,
justifyContent: 'center',
alignItems: 'center'
}
})
and LoginLightBox:
import React from 'react';
import { Animated , Text } from 'react-native';
import BaseLightbox from "./BaseLightbox";
export default class LoginLightbox extends React.Component {
render() {
return (
<BaseLightbox verticalPercent={0.7} horizontalPercent={0.5}>
<Text>Welcome to roocket</Text>
<Text>Learn React native</Text>
</BaseLightbox>
)
}
}
Related
I'm starting an app and I have two views at the moment, one called Splash and the other called Home. It happens that when the splash is over it leads me to the Home view, but in this view the user presses the button backwards, the app shows me the splash again. Is there a way to avoid this? the idea is that being in the Home view there is no way to roll back the application.
MainStackNavigator.js
import * as React from 'react'
import { NavigationContainer } from '#react-navigation/native'
import { createStackNavigator } from '#react-navigation/stack'
import Splash from '../views/Splash/Splash';
import Home from '../views/Home/Home';
const Stack = createStackNavigator()
function MainStackNavigator() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name='Splash' component={Splash} options={{ headerShown: false}} />
<Stack.Screen name='Home' component={Home} />
</Stack.Navigator>
</NavigationContainer>
)
}
export default MainStackNavigator
Splash.js
import React, { Component } from 'react'
import { View, ImageBackground, Image } from 'react-native'
// import SplashContext from '../../state/splashContext'
var bg = require('../../../assets/img/bg.png');
var logo = require('../../../assets/img/logo.png')
export default class Splash extends Component {
constructor(props) {
super(props);
setTimeout(() => {
this.props.navigation.navigate("Home");
}, 500)
}
render() {
return (
<ImageBackground
source={bg}
style={{ height: '100%', width: '100%' }}>
<View
style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Image source={logo}
style={{ height: 100, width: 100 }}
>
</Image>
</View>
</ImageBackground>
);
}
}
Home.js
import React, { Component } from 'react'
import { View, Text } from 'react-native'
export default class Splash extends Component {
render() {
return (
<View
style={{ flex: 1, padding: 10, alignItems: 'center', justifyContent: 'center' }}
>
<Text
style={{ fontSize: 30 }}
>Homse</Text>
</View>
);
}
}
App.js
import React from 'react';
import MainStackNavigator from './src/navigation/MainStackNavigator'
const App: () => React$Node = () => {
return (
<MainStackNavigator></MainStackNavigator>
);
};
export default App;
Using "navigate" will go to the next page adding it to the stack navigator. Instead you want to replace the current page (splash screen) with the home page. This can be done using
the replace function
this.props.navigation.replace("Home");
See https://reactnavigation.org/docs/navigation-prop/
You could use a modal to show the splash on the same screen while the information is loading instead of having two different views. Have a "loading" variable in the state of the view initialized to "true". This variable will be the "visibility" boolean for your modal. After everything loads, change the "loading" variable to "false".
Here's an example with "useState" hook:
const [isLoading, setIsLoading] = useState(true);
const loadInfo = async () => {
/*do your stuff*/
/*after stuff's done*/
setIsLoading(false);
};
if (isLoading) {
return (
<MySplashScreenModal/>
);
} else {
return (
<MyHomeScreen/>
);
}
The main reason for using the modal is because you can cover the entire screen with it, including the status bar.
I used this plugin for my android and ios app for the splash screen and it works great and smooth. I recommend everyone
React native bootsplash for splash screen
I just created a React Native app with Expo using expo init. Everything went fine. Then I went on and created a Home screen like so:
import React from 'react';
import { View, TextInput } from 'react-native';
export default class HomeScreen extends React.Component {
state = {
searchText: ""
}
render() {
return (
<View
style={{
flex: 1,
backgroundColor: 'white'
}}
>
<TextInput
placeholder="Search..."
value={this.state.searchText}
onChangeText={ (searchText) => this.setState({ searchText }) }
/>
</View>
);
}
}
I added it to my AppNavigator...
import { createAppContainer } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
import HomeScreen from '../screens/HomeScreen';
const AppNavigator = createStackNavigator({
Home: HomeScreen
});
export default createAppContainer(AppNavigator);
...which I in turn added to App.js:
import React from 'react';
import { StyleSheet, View, StatusBar, Platform } from 'react-native';
import { AppLoading } from 'expo';
import AppNavigator from './navigation/AppNavigator';
export default class App extends React.Component {
state = {
isLoadingComplete: false
}
render() {
if (!this.state.isLoadingComplete && !this.props.skipLoadingScreen) {
return (
<AppLoading
startAsync={this._loadResourcesAsync}
onError={this._handleLoadingError}
onFinish={this._handleFinishLoading}
/>
);
}
return (
<View style={styles.container}>
{Platform.OS === 'ios' && <StatusBar barStyle="default" />}
<AppNavigator />
</View>
);
}
_loadResourcesAsync = async () => { };
_handleLoadingError = error => {
console.warn(error);
};
_handleFinishLoading = () => {
this.setState({ isLoadingComplete: true });
};
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
Now, my problem is that my app looks like this:
As you can see, the horizontal margins are way too big, but I never set them to be like that. What am I doing wrong? I want the TextInput to stretch across the full screen.
Your HomeScreen Component will be as wide as its contents. You did not specify the width of the main View, therefore, it adjusted itself to be as wide the components inside. What you can do to resolve this issue is that you must provide width property in your Top level View's style.
And in order to get the Width of the screen, you can import Dimensions from react-native and use that like below:
const windowWidth = Dimensions.get('window').width;
and finally, you can assign the windowWidth to your view like so:
style={{flex:1, width: windowWidth, backgroundColor: 'white'}}
I'm working on an app in React Native. I want to make it so the styling of the panel labels on the bottom of the screen updates based on the panel the user is on.
As of now, I can get the index of the current panel that's showing, but I don't know how to make that update the styling of the labels.
The first panel
and the second panel
Basically when you use the same component and want to style it in different ways, your component's style property depends on either props or state. There are many ways to put different styles depending on your state/props, I'll provide just a few of them:
Ternary operation based on current state.
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
const styles = StyleSheet.create({ // Your styles go here
labelFirstTab: {
textColor: 'red',
},
labelSecondTab: {
textColor: 'blue',
},
});
class MyApp extends React.Component {
state = {
currentTab: 0,
};
getLabelStyles = () => {
const { currentTab } = this.state;
return currentTab === 0 ? styles.labelFirstTab : styles.labelSecondTab;
};
render() {
return (
<View style={{ flex: 1 }}>
{/* Let's say this is your label */}
<Text style={this.getLabelStyles()}>Hi! I'm a nice label.</Text>
</View>
);
}
}
Additional styling based on props (also could depend on state, it doesn't matter).
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
const styles = StyleSheet.create({
label: {
fontSize: 16,
textColor: 'black',
},
labelDarkMode: {
textColor: 'lightgrey',
},
}); // Your styles go here
class MyApp extends React.Component {
getLabelStyles = () => {
const { isDarkMode } = this.props;
const { label, labelDarkMode } = styles;
return [styles.label, isDarkMode && styles.labelDarkMode];
};
render() {
return (
<View style={{ flex: 1 }}>
{/* Let's say this is your label */}
<Text style={this.getLabelStyles()}>Hi! I'm a nice label.</Text>
</View>
);
}
}
You even can pass your styles directly from your props, leaving the whole logic to your parent component. Just make sure that you've passed styles from your parent component to the current one.
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
class MyApp extends React.Component {
render() {
const { labelStyles } = this.props;
return (
<View style={{ flex: 1 }}>
{/* Let's say this is your label */}
<Text style={labelStyles}>Hi! I'm a nice label.</Text>
</View>
);
}
}
Thank you E. Dn! This worked! Here's what I did.
const [activePanel, setActivePanel] = useState('nowPanel');
Swiping between panels calls a function:
const swipeNavigation = (index) => {
if (index === 0) {
setActivePanel('nowPanel');
} else {
setActivePanel('todayPanel');
}
};
Then within the actual View I want to style:
style={activePanel === 'nowPanel' ? styles.activePanel : null,}>
I'm quite new at react-redux, and currently am trying to build some stack application that will simply be some type of menu that will have it's sections with titles and when pressing the title it will show some simple text about it. So I'm using Flatlist for rendering all these sections, and the rendering works perfectly fine. It renders exactly 9 sections which is the number of my current objects, meaning that it has access to the data, plus when I try to change the font size of the title that these sections have to display, the size of the sections change as well, meaning that it definitely has access to the title strings as well, but for some reason the text is not showing up at all.
Here's how it looks:
I tried to change the text color, change size, change background color, add some padding, but section still doesn't show the text.
So here's where I implement the FlatList:
import React, { Component } from 'react';
import { FlatList } from 'react-native';
import { connect } from 'react-redux';
import ListItem from './ListItem';
class LibraryList extends Component {
renderItem(library) {
return <ListItem library={library} />;
}
render() {
console.log(this.props.libraries);
return (
<FlatList
data={this.props.libraries}
renderItem={this.renderItem}
keyExtractor={(library) => library.id.toString()}
/>
);
}
}
const mapStateToProps = state => {
return { libraries: state.libraries };
};
export default connect(mapStateToProps)(LibraryList);
Here I implement the section itself:
import React, { Component } from 'react';
import { Text } from 'react-native';
import { CardSection } from './common';
class ListItem extends Component {
render() {
const { titleStyle } = styles;
return (
<CardSection>
<Text style={titleStyle}>
{this.props.library.title}
</Text>
</CardSection>
);
}
}
const styles = {
titleStyle: {
color: 'black',
fontSize: 20,
fontWeight: '600',
}
};
export default ListItem;
And here's the code for the section itself:
import React from 'react';
import { View } from 'react-native';
const CardSection = (props) => {
return (
<View style={styles.containerStyle}>
{props.children}
</View>
);
};
const styles = {
containerStyle: {
borderBottomWidth: 1,
padding: 5,
backgroundColor: '#fff',
justifyContent: 'flex-start',
flexDirection: 'row',
borderColor: '#ddd',
}
};
export { CardSection };
Expected result would be for titles to show up in those 9 sections.
In ListItem replace {this.props.library.title} with {this.props.library.item.title} within the Text component.
I want to create some screen with stack and tabs navigator, but it seems not worked, it get error message like this error on virtual device...
Is this because the navigation or what?
This is my code
ConfirmActivation.js
import React, { Component } from 'react';
import { StyleSheet, Image } from 'react-native';
import { Container, Header, Content, Left, Right, Body, Text, StyleProvider,
Form, Item, Input, Label, Button, View } from 'native-base';
import { StackNavigator } from 'react-navigation';
import Icon from 'react-native-vector-icons/FontAwesome';
import getTheme from '../../../native-base-theme/components';
import material from '../../../native-base-theme/variables/material';
import Index from '../tabs/Index';
export default class sharpcs extends React.Component {
static navigationOptions = {
title: <Image source={require('../../assets/img/sharp_logo.png')} style={{width: 200, height: 50}} />,
header: null
}
render() {
return (
<AppNavigation/>
);
}
}
class ConfirmActivation extends Component{
static navigationOptions = {
title: <Image source={require('../../assets/img/sharp_logo.png')} style={{width: 200, height: 50}} />,
header: null
}
render() {
const { navigate } = this.props.navigation;
return (
<StyleProvider style={getTheme(material)}>
<Container style={styles.container} >
<Form style={styles.form} >
<Item floatingLabel>
<Label>Masukkan kode verifikasi</Label>
<Input keyboardType = 'numeric' maxLength = {13} />
</Item>
<View style={styles.buttonContainer} >
<Button
onPress={() =>
navigate('MainScreen')
} success style={{width: 125}} >
<Label style={{color: '#FFF', marginLeft: 24}} >
Lanjut
</Label>
</Button>
</View>
</Form>
</Container>
</StyleProvider>
);
}
}
const App = StackNavigator({
ThisScreen: { screen: ConfirmActivation },
MainScreen: { screen: Index }
});
const AppNavigation = () => (
<App />
);
const styles = StyleSheet.create({
form: {
flex: 2,
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center'
},
container: {
padding: 20
},
buttonContainer: {
marginTop: 20,
flexDirection: 'row',
alignSelf: 'flex-end'
}
});
Index.js
import React, { Component } from 'react';
export default class Index extends React.Component {
render() {
return null;
}
}
The cause of the error is the title in the navigationOptions in sharpcs class. It expects a string. You had provided it an image component. Although the image appears, but this error appears when navigating. So use instead of title, headerTitle