(react-native)There is a splash image that I drew, and I want to increase the time it takes to appear - react-native

The picture file I drew is in ASSETS
You can tell from this picture
I want to set the time when this image appears
I don't know much about coding because I'm a beginner
I want you to modify my whole code
I really want to complete this app
Please help me
I want to make the splash image appear for about 5 seconds
import React, { useRef, useState, useCallback, useEffect } from "react";
import { BackHandler, Platform, StyleSheet,ActivityIndicator } from "react-native";
import { WebView } from "react-native-webview";
export default function App() {
const webView = useRef();
const [canGoBack, setCanGoBack] = useState(false);
const handleBack = useCallback(() => {
if (canGoBack && webView.current) {
webView.current.goBack();
return true;
}
return false;
}, [canGoBack]);
useEffect(() => {
BackHandler.addEventListener("hardwareBackPress", handleBack);
return () => {
BackHandler.removeEventListener("hardwareBackPress", handleBack);
};
}, [handleBack]);
const App = () => (
<View style={[styles.container, styles.horizontal]}>
<ActivityIndicator />
<ActivityIndicator size="large" />
<ActivityIndicator size="small" color="#0000ff" />
<ActivityIndicator size="large" color="#00ff00" />
</View>
);
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
},
horizontal: {
flexDirection: 'row',
justifyContent: 'space-around',
padding: 10,
},
});
const platformStyles = StyleSheet.create({
webView: Platform.OS === 'ios'
? { marginTop: 30, marginBottom: 40 }
: { marginTop: 30 }
});
return (
<WebView
ref={webView}
source={{ uri: "https://www.talesrunnerbestguild.co.kr/" }}
style = {platformStyles.webView}
onLoadProgress={(event) => setCanGoBack(event.nativeEvent.canGoBack)}
/>
);
}

So what you can do is once your splash image appears finish then launch default View where you can show splash image for 5 seconds, which you can set timer. Then navigate to another screen whichever you want to show after your timer time end ie after 5 seconds.

As You are using expo. You can achieve it by using expo-splash-screen function SplashScreen.preventAutoHideAsync() and SplashScreen.hideAsync()
Install expo-splash-screen in your project root.
expo install expo-splash-screen
Here is what you need to add to your code. I modify it from above expo guide
export default function App() {
...
const [appIsReady, setAppIsReady] = useState(false)
async function preventSplashHide() {
try {
// Manually stop hiding the splash screen
await SplashScreen.preventAutoHideAsync()
// 5 second timer
await new Promise(resolve => setTimeout(resolve, 5000))
} finally {
setAppIsReady(true);
}
}
// call preventSplashHide() when mount
useEffect(() => {
preventSplashHide()
}, [])
const hideSplash = useCallback(async () => {
if (appIsReady) {
// hide the splash screen when root view is shown(when appIsReady is true)
await SplashScreen.hideAsync()
// meanwhile the callback is listening on appIsReady
}
}, [appIsReady])
if (!appIsReady) {
return null
}
return (
<View
onLayout={hideSplash}>
...
</View>
);
}

Related

I want to make a bottom bar

I want to make lower under the bar.But I don't know how to make. Press the lower bar to help me seyeo can get a page, I want I want to make.And I want to put the image that I want in the bottom bar Tell me what to do first I need your help I searched hard on Google, but there is no code similar to mine, so I keep getting it wrong or weird
import React, { useRef, useState, useCallback, useEffect } from 'react';
import {
View,
BackHandler,
Platform,
StyleSheet,
ActivityIndicator,
} from 'react-native';
import { WebView } from 'react-native-webview';
import { Image } from "react-native";
const DELAY_BEFORE_WEBVIEW = 10; // <--- seconds before webview load
export default function App() {
// ref
const webView = useRef();
const [canGoBack, setCanGoBack] = useState(false);
const handleBack = useCallback(() => {
if (canGoBack && webView.current) {
webView.current.goBack();
return true;
}
return false;
}, [canGoBack]);
// effects
useEffect(() => {
BackHandler.addEventListener('hardwareBackPress', handleBack);
return () => {
BackHandler.removeEventListener('hardwareBackPress', handleBack);
};
}, [handleBack]);
useEffect(() => {
setTimeout(() => {
setIsLoading(false);
}, 1000 * DELAY_BEFORE_WEBVIEW);
}, []);
// states
const [isLoading, setIsLoading] = useState(true);
return (
<View style={styles.container}>
<WebView
ref={webView}
source={{ uri: 'https://www.talesrunnerbestguild.co.kr/' }}
style={styles.webView}
onLoadProgress={(event) => setCanGoBack(event.nativeEvent.canGoBack)}
/>
{isLoading && <CenterLoader />}
</View>
);
}
const CenterLoader = () => (
<View style={styles.loaderContainer}>
<Image source={require('/workspace/talesrunner23/assets/js34.png/')}
style={{height:115,width:90}}/>
</View>
);
const styles = StyleSheet.create({
container: { flex: 1 },
loaderContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
position: 'absolute',
width: '100%',
height: '100%',
backgroundColor:'white' // <-- comment this to show webview while loading
},
webView:
Platform.OS === 'ios'
? { marginTop: 30, marginBottom: 40 }
: { marginTop: 30 },
});

I want to make a bottom bar The bottom bar goes to the page I want when I click it

enter image description here
I want to make a bottom bar The bottom bar goes to the page I want when I click it
I want to make it similar to that picture
I want to make a bottom bar like that
I've been googling hard, but I can't find anything similar to me
https://reactnavigation.org/docs/bottom-tab-navigator/
I want to use the code in the address over there, but I don't know
import React, { useRef, useState, useCallback, useEffect } from
'react';
import {
View,
BackHandler,
Platform,
StyleSheet,
ActivityIndicator,
} from 'react-native';
import { WebView } from 'react-native-webview';
import { Image } from "react-native";
const DELAY_BEFORE_WEBVIEW = 10; // <--- seconds before webview load
export default function App() {
// ref
const webView = useRef();
const [canGoBack, setCanGoBack] = useState(false);
const handleBack = useCallback(() => {
if (canGoBack && webView.current) {
webView.current.goBack();
return true;
}
return false;
}, [canGoBack]);
// effects
useEffect(() => {
BackHandler.addEventListener('hardwareBackPress', handleBack);
return () => {
BackHandler.removeEventListener('hardwareBackPress', handleBack);
};
}, [handleBack]);
useEffect(() => {
setTimeout(() => {
setIsLoading(false);
}, 1000 * DELAY_BEFORE_WEBVIEW);
}, []);
// states
const [isLoading, setIsLoading] = useState(true);
return (
<View style={styles.container}>
<WebView
ref={webView}
source={{ uri: 'https://www.talesrunnerbestguild.co.kr/' }}
style={styles.webView}
onLoadProgress={(event) =>
setCanGoBack(event.nativeEvent.canGoBack)}
/>
{isLoading && <CenterLoader />}
</View>
);
}
const CenterLoader = () => (
<View style={styles.loaderContainer}>
<Imagesource{require('/workspace/talesrunner23/assets/js34.png/')}
style={{height:115,width:90}}/>
</View>
);
const styles = StyleSheet.create({
container: { flex: 1 },
loaderContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
position: 'absolute',
width: '100%',
height: '100%',
backgroundColor:'white' // <-- comment this to show webview while
loading
},
webView:
Platform.OS === 'ios'
? { marginTop: 30, marginBottom: 40 }
: { marginTop: 30 },
});

React Native - How to extract data from FaceDetector of Expo SDK?

I’m new to React Native and still learning React and JavaScript. I’m practicing on Expo snack with Expo's FaceDetector (SDK 37) and managed to generate data about faces. However, I couldn't (or don't know how to) extract these data. My goal for now is to render the rollAngle data in a Text component.
Here is the code I used in Expo Snack and tested with my Android cellphone:
import React, { useState, useEffect } from 'react';
import { Text, View } from 'react-native';
import { Camera } from 'expo-camera';
import * as FaceDetector from 'expo-face-detector'
export default function App() {
const [hasPermission, setHasPermission] = useState(null);
const [faces, setFaces] = useState([])
const faceDetected = ({faces}) => {
setFaces({faces})
console.log({faces})
}
useEffect(() => {
(async () => {
const { status } = await Camera.requestPermissionsAsync();
setHasPermission(status === 'granted');
})();
}, []);
if (hasPermission !== true) {
return <Text>No access to camera</Text>
}
return (
//<View style={{ flex: 1 }}>
<Camera
style={{ flex: 1 }}
type='front'
onFacesDetected = {faceDetected}
FaceDetectorSettings = {{
mode: FaceDetector.Constants.Mode.fast,
detectLandmarks: FaceDetector.Constants.Landmarks.all,
runClassifications: FaceDetector.Constants.Classifications.none,
minDetectionInterval: 5000,
tracking: false
}}
>
<View
style={{
flex: 1,
backgroundColor: 'transparent',
flexDirection: 'row',
}}>
<Text style= {{top:200}}> is {faces[0].rollAngle} </Text>
</View>
</Camera>
//</View>
);
}
In the snack console, I see results like this:
Results in the Snack console
I tried to replace the faceDetected function with the following code:
const faceDetected = (faces) => {
setFaces(faces)
console.log(faces)
}
Then, the console shows slightly different results: Results in Snack console
I tried both ways to render rollAngle, but an error message showed up and said face[0].rollAngle is undefined and is not an object.
Please help and any suggestion is appreciated.
Thank you.
You may have resolved this problem.
"faces.faces" worked for me..
const faceDetected = (faces) => {
setFaces(faces.faces)
}
I am new to react-native..
So if you resolved it by some other way please let us know.
I believe I have fixed your problem:
import React, { useState, useEffect } from 'react';
import { Text, View } from 'react-native';
import { Camera } from 'expo-camera';
import * as FaceDetector from 'expo-face-detector'
export default function App() {
const [hasPermission, setHasPermission] = useState(null);
const [faces, setFaces] = useState([])
const faceDetected = ({faces}) => {
setFaces(faces) // instead of setFaces({faces})
console.log({faces})
}
useEffect(() => {
(async () => {
const { status } = await Camera.requestPermissionsAsync();
setHasPermission(status === 'granted');
})();
}, []);
if (hasPermission !== true) {
return <Text>No access to camera</Text>
}
return (
//<View style={{ flex: 1 }}>
<Camera
style={{ flex: 1 }}
type='front'
onFacesDetected = {faceDetected}
FaceDetectorSettings = {{
mode: FaceDetector.Constants.Mode.fast,
detectLandmarks: FaceDetector.Constants.Landmarks.all,
runClassifications: FaceDetector.Constants.Classifications.none,
minDetectionInterval: 5000,
tracking: false
}}
>
<View
style={{
flex: 1,
backgroundColor: 'transparent',
flexDirection: 'row',
}}>
{faces[0] && <Text style= {{top:200}}> is {faces[0].rollAngle} </Text>} // only render text if faces[0] exists
</View>
</Camera>
//</View>
);
}
I think your main problem was you were using
setFaces({faces})
instead of
setFaces(faces)

How to hide components when keyboard is up?

Is there a way to hide components when the keyboard shows, aside from installing packages?
Using the code sample from the Keyboard documentation, I would do something like this:
class Example extends Component {
state = {keyboardOpen: false};
componentDidMount() {
this.keyboardDidShowListener = Keyboard.addListener(
'keyboardDidShow',
this._keyboardDidShow,
);
this.keyboardDidHideListener = Keyboard.addListener(
'keyboardDidHide',
this._keyboardDidHide,
);
}
componentWillUnmount() {
this.keyboardDidShowListener.remove();
this.keyboardDidHideListener.remove();
}
_keyboardDidShow() {
this.setState({
keyboardOpen: true
});
}
_keyboardDidHide() {
this.setState({
keyboardOpen: false
});
}
render() {
return (
{!this.state.keyboardOpen && <MyComponent />}
);
}
}
Basically, in componentDidMount you subscribe to the show and hide keyboard events. You keep track of the Keyboard current state in your Component state thanks to this.state.keyboardOpen and you conditionally display MyComponent based on the value of this.state.keyboardOpen in your render method.
For those using functional components, here is a hook that you could use to detect when the keyboard is opened and closed.
import { useEffect, useState, useMemo } from "react";
import { Keyboard } from "react-native";
const useKeyboardOpen = () => {
const [isKeyboardOpen, setIsKeyboardOpen] = useState(false);
useEffect(() => {
const keyboardOpenListener = Keyboard.addListener("keyboardDidShow", () =>
setIsKeyboardOpen(true)
);
const keyboardCloseListener = Keyboard.addListener("keyboardDidHide", () =>
setIsKeyboardOpen(false)
);
return () => {
if (keyboardOpenListener) keyboardOpenListener.remove();
if (keyboardCloseListener) keyboardCloseListener.remove();
};
}, []);
return isKeyboardOpen;
};
export default useKeyboardOpen;
And this is how I use it in my projects:
import { useTheme } from "react-native-paper";
import useKeyboardOpen from "hooks/useKeyboardOpen";
export const Login = () => {
const theme = useTheme();
const isKeyboardOpen = useKeyboardOpen();
const styles = useStyles(theme, isKeyboardOpen);
return (
<View style = {styles.container}>
<View style = {styles.logo}>
<Logo />
</View>
<View style = {styles.form}>
....
</View>
</View>
);
};
const useStyles = (theme, isKeyboardOpen) = (
StyleSheet.create({
container: {
flex: 1,
},
logo: {
flex: 1,
marginTop: 20,
justifyContent: "center",
alignItems: "center",
...(isKeyboardOpen && {
display: "none",
}),
},
form: {
flex: 1,
}
})
);
I made this into a npm package if anyone is interested.
https://github.com/TIKramer/react-native-hide-onkeyboard
You can hide the view by using HideOnKeyboard> </HideOnKeyboard

Expo SDK 29 FlatList onRefresh not calling

Using Expo SDK 29 for a react native application.
I would like to use a flat list component. This makes up the entirety of a SafeAreaView component. I make this point as there are lots of issues relating to a flat list inside of a scroll view which this is not.
The flat list shows a list of jobs.
I have added a jobLoading boolean to the redux state to manage when the list should show as refreshing and can confirm that this toggles as expected when firing the actions to fetch the data and the success.
When i add the props to the flat list for onRefresh and refreshing the component seems to work by showing the activity indicator in the UI but does not fire the onRefresh function. I have tried implementing the call in numerous ways but nothing happens. The result is that the activity indicator shows itself and never disappears.
As it's Expo SDK 29 the React Native version is 0.55.4
Anyone have any ideas of what to try. I've spent a couple of hours looking at this trying various things but suggestions are welcome.
Thanks in advance.
EDIT: Added the code for reference. Reducer for refreshing sets true when fetchJobs() is dispatched and false when a success or error is recieved. The console log for onRefresh never triggers.
import * as React from 'react'
import * as actions from '../../redux/actions'
import { ActivityIndicator, FlatList, KeyboardAvoidingView, Dimensions, SafeAreaView, StyleSheet, View } from 'react-native'
import { ApplicationState, JobState, Job } from '../../redux'
import { Button, Form, Input, Item, Text, Icon } from 'native-base'
import { JobListItem } from './jobListItem'
import { StateHandlerMap, compose, lifecycle, withPropsOnChange, withStateHandlers } from 'recompose'
import { connect } from 'react-redux'
interface ReduxStateProps {
jobs: JobState
refreshing: boolean
screenOrientation: string
}
interface ReduxDispatchProps {
fetchJobs: (param?: string) => any
}
export interface DataItem {
key: string
data: Job
}
interface ListProps {
jobList: DataItem[]
}
interface SearchStateProps {
timer: number | undefined
searchString: string
}
interface SearchHandlerProps extends StateHandlerMap<SearchStateProps> {
updateSearch: (searchString: string) => any
setTimer: (timer: number | undefined) => any
}
type OuterProps = {}
type InnerProps = OuterProps & ReduxStateProps & ReduxDispatchProps & ListProps & SearchStateProps & SearchHandlerProps
const enhance = compose<InnerProps, OuterProps>(
connect<ReduxStateProps, ReduxDispatchProps, OuterProps, ApplicationState>(
state => ({
jobs: state.job,
refreshing: state.jobLoading,
screenOrientation: state.screenOrientation
}),
dispatch => ({
fetchJobs: (param?: string) => dispatch(actions.jobs.request({ param }))
})
),
withPropsOnChange<ListProps, OuterProps & ReduxStateProps & ReduxDispatchProps>(
['jobs', 'screenOrientation'],
props => ({
jobList: props.jobs && Object.keys(props.jobs).map(job => ({ key: job, data: props.jobs[Number(job)] }))
})
),
withStateHandlers<SearchStateProps, SearchHandlerProps, OuterProps>(
{
timer: undefined,
searchString: ''
},
{
updateSearch: state => (searchString: string) => ({ searchString }),
setTimer: state => (timer: number | undefined) => ({ timer })
}
),
lifecycle<InnerProps, {}>({
componentDidMount() {
this.props.fetchJobs()
}
})
)
export const JobList = enhance(({ fetchJobs, jobList, refreshing, screenOrientation, searchString, setTimer, timer, updateSearch }) => {
const onSearchChange = (search: string) => {
clearTimeout(timer)
updateSearch(search)
const timing = setTimeout(() => {
fetchJobs(search)
}, 500)
setTimer(timing)
}
const onRefresh = () => {
console.log('requesting refresh')
fetchJobs()
}
return (
<SafeAreaView style={{ flex: 1}}>
<KeyboardAvoidingView style={{ flexDirection: 'row', justifyContent: 'space-evenly', paddingTop: 3, paddingRight: 3 }}>
<Form style={{ flex: 1, paddingLeft: 10, paddingRight: 10 }}>
<Item>
<Input
value={searchString}
onChangeText={(text: string) => onSearchChange(text)}
placeholder='Search'
/>
</Item>
</Form>
<Button onPress={() => {fetchJobs(); updateSearch('')}}>
<Icon name='refresh' />
</Button>
</KeyboardAvoidingView>
{refreshing &&
<View style={styles.refreshContainer}>
<Text style={{ paddingBottom: 10 }}>Fetching Data</Text>
<ActivityIndicator />
</View>
}
<FlatList
keyExtractor={item => item.key}
data={jobList}
renderItem={({ item }) =>
<JobListItem
screenOrientation={screenOrientation}
item={item}
/>
}
onRefresh={onRefresh}
refreshing={refreshing}
/>
</SafeAreaView>
)
})
const styles = StyleSheet.create({
refreshContainer: {
height: 60,
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center'
}
})
I'm having the exact same issue and I'm using expo SDK 30. But my case is a little bit different. The onRefresh function is called everytime I pull, however if I scroll down my list, and scroll back up fast, the loading indicator shows up, but my onRefresh function is not called.
My refreshing prop is set on my reducer, and my onRefresh function dispatches an action that fetches data and set refreshing true and false.
Here is my code:
class NoticiasScreen extends Component {
static navigationOptions = {
header: <Header
title='Notícias Alego'
leftComponent={<Image source={require('../../../assets/images/play_grande.png')} style={imageStyle} resizeMode='contain'/>}
/>
}
constructor(props) {
super(props);
this.renderItem = this.renderItem.bind(this);
this.keyExtractor = this.keyExtractor.bind(this);
this.renderContent = this.renderContent.bind(this);
this.navigateToNoticias = this.navigateToNoticias.bind(this);
this.carregarMaisNoticias = this.carregarMaisNoticias.bind(this);
this.onRefresh = this.onRefresh.bind(this);
}
componentDidMount() {
this.props.carregarNoticias(this.props.pagina);
}
renderItem({item}) {
return (
<NoticiaListItem noticia={item} abrirNoticia={this.navigateToNoticias} />
);
}
keyExtractor(item) {
return item.id.toString();
}
navigateToNoticias(noticia) {
this.props.navigation.navigate('NoticiasExibir', { id: noticia.id });
}
onRefresh() {
console.log('onRfresh');
this.props.carregarNoticias(1, true);
}
carregarMaisNoticias() {
const { carregarNoticias, pagina } = this.props;
carregarNoticias(pagina + 1);
}
renderContent() {
const { noticias, carregandoNoticias, erroNoticias } = this.props;
if(noticias.length === 0 && carregandoNoticias) {
return (
<View style={styles.containerCenter}>
<ActivityIndicator size="large" color={colors.verde}/>
</View>
);
}
if(erroNoticias) {
return (
<View style={styles.containerCenter}>
<Text style={styles.message}>{erroNoticias}</Text>
<TouchableOpacity hitSlop={hitSlop15}>
<Text>Recarregar</Text>
</TouchableOpacity>
</View>
)
}
return (
[<TextInput
style={styles.textInput}
placeholder='Pesquise'
key='pesquisa'
underlineColorAndroid='transparent'
/>,
<FlatList
data={noticias}
renderItem={this.renderItem}
keyExtractor={this.keyExtractor}
style={styles.list}
key='lista'
onRefresh={this.onRefresh}
refreshing={carregandoNoticias}
onEndReached={this.carregarMaisNoticias}
onEndReachedThreshold={0.1}
/>]
)
}
render() {
return (
<SafeAreaView style={styles.safeArea}>
<View style={styles.container}>
{this.renderContent()}
</View>
</SafeAreaView>
);
}
}
function mapStateToProps(state) {
return {
noticias: state.intranet.noticias,
pagina: state.intranet.pagina,
erroNoticias: state.intranet.erroNoticias,
carregandoNoticias: state.intranet.carregandoNoticias
}
}
function mapDispatchToProps(dispatch) {
return {
carregarNoticias: (pagina, recarregar) => dispatch(ActionCreator.carregarNoticias(pagina, recarregar))
}
}
export default connect(mapStateToProps, mapDispatchToProps)(NoticiasScreen);
No idea what's going on. Any help is appreciated.
EDIT:
I fixed it somehow. I added the onMomentScrollBegin prop to prevent my flatList from rendering twice on Render, and that fixed this issue.
here is what I added:
constructor(props) {
super(props);
...
this.onRefresh = this.onRefresh.bind(this);
this.onMomentumScrollBegin = this.onMomentumScrollBegin.bind(this);
this.onEndReachedCalledDuringMomentum = true; //PUT THIS HERE
}
onRefresh() {
this.props.carregarNoticias(1, true);
}
carregarMaisNoticias() {
if(!this.onEndReachedCalledDuringMomentum){
const { carregarNoticias, pagina } = this.props;
carregarNoticias(pagina + 1);
this.onEndReachedCalledDuringMomentum = true;
}
}
onMomentumScrollBegin() {
this.onEndReachedCalledDuringMomentum = false;
}
render() {
<OptimizedFlatList
data={noticias}
renderItem={this.renderItem}
keyExtractor={this.keyExtractor}
style={styles.list}
key='lista'
onRefresh={this.onRefresh}
refreshing={carregandoNoticias}
onMomentumScrollBegin={this.onMomentumScrollBegin} //PUT THIS HERE
onEndReached={this.carregarMaisNoticias}
onEndReachedThreshold={0.1}
/>
}