I have a problem. I have a listview. I want to add loading image while wait show image in screen.
I've been tried react-native-fast-image, react-native-image-progress. But not.
You can help me. thankssss.
Index.js
<ListView
enableEmptySections
style={styles.list}
dataSource={this.state.dataSource}
renderRow={rowData => <ArtStreamRow artwork={rowData} />}
scrollRenderAheadDistance={3000}
initialListSize={30}
onEndReached={this.onEndReached}
onEndReachedThreshold={900}
refreshControl={
<RefreshControl
refreshing={this.props.isRefreshing}
onRefresh={this.onRefresh}
/>
ArtStreamRow.js
class ArtStreamRow extends PureComponent {
render() {
const {
artwork,
} = this.props;
return (
<View style={styles.container}>
<TouchableNativeFeedback
onPress={viewArtworkDetail.bind(this, artwork)}
background={Platform.OS === 'android' ?
TouchableNativeFeedback.SelectableBackground() : ''}
>
<Image
source={{ uri: getUrl(artwork) }}
style={styles.artworkImage}
resizeMode={Image.resizeMode.cover}
/>
</TouchableNativeFeedback>
</View>
)
}
here, loading image, I want to add.
Related
i get image url correct and passed as props but image not showing in my app
main screen
here main screen that render FlatList data = products that include image url and i log that and getting correct but image not showing
const products = useSelector(state => state.products.availableProducts);
return(
<FlatList numColumns ={2}
data={products}
keyExtractor={item => item.id}
renderItem={itemData => (
<ProductItem
image={itemData.item.imageUrl}
title={itemData.item.title}
price={itemData.item.price}
onSelect={()=>{
props.navigation.navigate('detail', {
productId: itemData.item.id,
})
}}
>
</ProductItem>
)}
/>
ProductItem component
<View style={style.product}>
<View style={style.touchable}>
<TouchableCmp onPress={props.onSelect} useForeground>
<View>
<View style={style.imageContainer}>
<Image style={style.image} source={{uri: props.image}} />
</View>
<View style={style.detail}>
<Text style={style.title}>{props.title}</Text>
<Text style={style.price}>{props.price}SDG</Text>
</View>
</View>
</TouchableCmp>
<View style={{marginTop:1}}>{props.delete}</View>
</View>
</View>
¿What properties does the style tag "style.image" have?
There may be a problem with the height or width of the image.
i find the should add http:// to image url because i am not adding when saving data
code will be like
<Image style={styles.image} source=
{{uri:`http://${singleproduct.imageUrl}`}} />
I've tried several times with , but didn't work. Maybe I don't know where to put it in code. I'm a beginner in react-native, but I need your help. Please share your answers!
render() {
console.log('render register -> renderComponent');
return (
<View style={styles.container}>
<Image source={require('../components/logo.png')} />
<KeyboardAvoidingView style={styles_register.containerView} behavior="padding">
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View style={styles_register.registerScreenContainer}>
<View style={styles_register.registerFormView}>
<ThemeProvider theme={theme}>
<Button
buttonStyle={styles.loginButtonn}
onPress={() => {
this.registerWithFacebook();
}}
title = "Login with Facebook"
/>
</ThemeProvider>
</View>
</View>
</TouchableWithoutFeedback>
</KeyboardAvoidingView>
</View>
);
}
}
First of all, make sure that your image is in that path ../components/logo.png, also set the size to your image component. Since you are beginner always start with the documentation
<Image
style={{width: 50, height: 50}}
source={require('../components/logo.png')}
/>
render() {
console.log('render register -> renderComponent');
return (
I have a React Native App built with ExpoKit SDK 32. I have a main switch navigator (from React Navigation) which starts with a Loading Screen, there I do some business logic to decide what screen should load next (Screen A or B), on the next screen I disable the Splash Screen.
The problem is: Whenever I move from the Loading Screen to screen A, I get a White flash.
I have not seem it happen on iOS, only on Android.
Screen A has a imageBackground Component on the whole screen. The image is cached and its the same as the splash screen.
I've tried rendering an image equal to the SplashScreen on the background of the Loading Screen. Same result.
Then I put on my componentDidMount of Screen A SplashScren.hide(). Same result.
The best outcome as been putting 'SplashScreen.hide()' on the onLoadEnd of my background Image of Screen A.
Any help is appreciated! Is there a better way to deal with this kind of situation involving the Switch Component on React Navigation?
This is how my Screen A looks now:
async imageLoaded() {
SplashScreen.hide();
try {
const usuario = await SecureStore.getItemAsync(LOGIN_USUARIO_LOCAL_AUTH);
if (usuario) {
await this.localAuth();
}
} catch (err) {
// faz nada
}
}
....
render() {
const { usuario, senha } = this.state;
const { logando, localAuthHardware } = this.props;
const labelHardware = localAuthLabel(localAuthHardware);
return (
<SafeAreaView style={styles.safeArea}>
<ImageBackground
source={require('../../../assets/images/start.png')}
resizeMode="cover"
style={styles.container}
imageStyle={styles.container}
onLoadEnd={this.imageLoaded}
fadeDuration={0}
>
<KeyboardAwareScrollView alwaysBounceVertical={false} keyboardShouldPersistTaps="handled">
<Image
source={require('../../../assets/images/baladapp-icone.png')}
style={styles.baladappicone}
resizeMode="contain"
fadeDuration={0}
/>
<View style={styles.baladappView}>
<Image
source={require('../../../assets/images/BaladAPP.png')}
resizeMode="contain"
style={styles.baladapp}
fadeDuration={0}
/>
<Text style={styles.produtorText}>PRODUTOR</Text>
</View>
<View style={styles.formView}>
<TextInput
placeholder="Usuário"
style={[styles.input, { elevation: 1.3 }]}
underlineColorAndroid="transparent"
value={usuario}
onChangeText={this.changeUsuario}
keyboardType={Platform.OS === 'ios' ? 'email-address' : 'visible-password'}
autoCorrect={false}
autoCapitalize="none"
/>
<PasswordInputField
placeholder="Senha"
style={styles.input}
enablesReturnKeyAutomatically
underlineColorAndroid="transparent"
value={senha}
onChangeText={this.changeSenha}
containerStyle={[styles.containerPasswordStyle, { elevation: 1.3 }]}
onSubmitEditing={this.login}
/>
<TouchableOpacity
onPress={this.abrirRecuperarSenha}
style={styles.esqueceuTextView}
hitSlop={hitSlop15}
>
<Text style={styles.esqueceuText}>Esqueceu a senha?</Text>
</TouchableOpacity>
<Button
text="ACESSAR SISTEMA"
containerStyle={styles.button}
textStyle={styles.buttonText}
onPress={this.login}
loading={logando}
loadingColor={colors.branco}
/>
{localAuthHardware.length > 0 && (
<TouchableOpacity
onPress={this.localAuth}
style={styles.localAuthView}
hitSlop={hitSlop15}
>
<Text style={styles.esqueceuText}>{`Acessar com ${labelHardware}`}</Text>
</TouchableOpacity>
)}
</View>
</KeyboardAwareScrollView>
</ImageBackground>
</SafeAreaView>
);
}
I have multiple videos from an array map that each have an activity indicator. I want to set to false once the video is loaded.
Can someone please explain a method where I can do this for each video individually. At the moment on the onLoad callback it's just setting a global state value.
{revArray.map((camera,index) => (
<View key={'camera'+index} style={{backgroundColor:'#eeeeee'}}>
<TouchableOpacity onPress={() => {this.removePrompt(camera.title.toString())}} style={{padding:6,position:'absolute',right:4,top:8,zIndex:999}}><Image source={require('../Images/delete1.png')} style={{width:16,height:16}}></Image></TouchableOpacity>
<Text key={'title'+index} style={{color:'#113b92',textAlign:'center',padding:10,fontSize:16,fontFamily:'Lato-Bold'}}>{camera.title}</Text>
<View style={{backgroundColor:'#000'}}>
{this.state.isLoading ? ( <View style={{ position: 'absolute',left: 0,right: 0,top: 0,bottom: 0,alignItems: 'center',justifyContent: 'center',zIndex:9999}}>
<ActivityIndicator size="large" color={'#000'} style={{backgroundColor:'#fff', padding:6, borderRadius:30}} />
</View>
): (null)}
<Video
onLoad={()=>{this.setState({isLoading:false})}}
key={'video'+index}
ref={(ref: Video) => { this.video = ref }}
style={styles.fullScreen}
resizeMode='cover'
source={{uri: camera.video+'?'+new Date()}}
repeat={true}
/>
</View>
</View>
))}
Because isLoading is the state of the component rendering each of the videos in the array its only ever going to control all of them... What you want to do here is render a "container" component with its own state for each of these -
class VideoWrapper extends React.Component {
state = {
isLoading: true
}
<View key={'camera'+index} style={{backgroundColor:'#eeeeee'}}>
...
<Video
onLoad={()=>{this.setState({isLoading:false})}}
key={'video'+index}
ref={(ref: Video) => { this.video = ref }}
style={styles.fullScreen}
resizeMode='cover'
source={{uri: camera.video+'?'+new Date()}}
repeat={true}
/>
</View>
}
And to render -
{revArray.map((camera,index) =>
<VideoWrapper key={camera.id} camera={camera} index={index} />
)}
This way each video in the array controls its own state.
React Native's ListView has a built-in pull-to-refresh control called RefreshControl. It's super easy to use.
I'd like to customize the look and feel of the control to use a different visual design, such as using a material design progress indicator.
How can I customize the look of the RefreshControl in React Native?
You can outsmart it by doing:
setting transparent properties to ListView
Adding component with absolute position
Example:
<View style={{height:Dimensions.get('window').height}}>
{/* custom refresh control */}
<View
style={{position:'absolute',
width:Dimensions.get('window').width, height:60,
alignItems:'center', justifyContent:'center'}}>
<Progress.CircleSnail
color={['red', 'green', 'blue']}
duration={700} />
</View>
{/* list view*/}
<ListView
dataSource={this.state.dataSource}
refreshControl={
<RefreshControl
onLayout={e => console.log(e.nativeEvent)}
// all properties must be transparent
tintColor="transparent"
colors={['transparent']}
style={{backgroundColor: 'transparent'}}
refreshing={this.state.refreshing}
onRefresh={() => {
this.setState({refreshing:true});
setTimeout(() => {
this._addRows()
}, 2000);
}}
/>
}
renderRow={(rowData) => <Text>{rowData}</Text>} />
</View>
This is the result:
You can totally do this. It requires some work though.
You can start by writing something like this.
<View style={styles.scrollview}>
<View style={styles.topBar}><Text style={styles.navText}>PTR Animation</Text></View>
<View style={styles.fillParent}>
<Text>Customer indicator goes here...</Text>
</View>
<View style={styles.fillParent}>
<ListView
style={{flex: 1}}
dataSource={this.state.dataSource}
renderRow={(rowData) => <View style={styles.row}><Text style={styles.text}>{rowData}</Text></View>}
ref='PTRListView'
/>
</View>
</View>
When you'll pull to refresh, you should see the text "Custom indicator goes here..."
Following this pattern, you can place your component instead of just a view and a text.
For the credits, thanks to this article for the idea.
I did it using react-native-pull-to-refresh-custom lib
First create custom loader ListRefreshLoader
import React from 'react';
import {StyleSheet, View} from 'react-native';
import colors from '../../assets/colors';
import {wp} from '../../styles/responsiveScreen';
import Circuler from './Circuler';
const ListRefreshLoader = ({refreshing}) => {
return (
<View>
{refreshing ? (
<View style={styles.container}>
<Circuler color={colors.gray} size={wp(6)} />
</View>
) : null}
</View>
);
};
const styles = StyleSheet.create({
container: {
width: wp(15),
height: wp(15),
alignSelf: 'center',
justifyContent: 'center',
alignItems: 'center',
},
});
export default ListRefreshLoader;
Then use following way
import PullToRefresh from 'react-native-pull-to-refresh-custom';
import ListRefreshLoader from '../../components/Loader/ListRefreshLoader';
<PullToRefresh
HeaderComponent={() => <ListRefreshLoader refreshing={refreshing} />}
headerHeight={60}
refreshTriggerHeight={60}
refreshingHoldHeight={60}
refreshing={refreshing}
onRefresh={onRefresh}
style={styles.list}>
<FlatList
data={friendsList}
viewabilityConfig={{
itemVisiblePercentThreshold: 90,
}}
maxToRenderPerBatch={100}
removeClippedSubviews
style={styles.list}
keyExtractor={(item, index) => index.toString()}
showsVerticalScrollIndicator={false}
persistentScrollbar
renderItem={renderItem}
ItemSeparatorComponent={() => {
return <View style={styles.listSeperator} />;
}}
ListEmptyComponent={totalUserFriends === 0 ? renderEmpty() : null}
ListHeaderComponent={
totalUserFriends !== 0 || searchText !== '' ? (
<ListSearch
placeHolder={`${t('Search')}...`}
searchText={searchText}
style={styles.searchStyle}
fontName={'roboto-regular'}
onSearchChange={(text) => setSearchText(text)}
onClearSearch={() => {
setSearchText('');
}}
onEndEditing={() => setSearchText(searchText)}
/>
) : null
}
/>
</PullToRefresh>
I have written custom RefreshControl by merging below 2 methods
viewablityConfig of flatlist/sectionList will help in identifying the top element of the data.
if (viewableItems[0]?.item?.url === firstCategoryUrl) {
updateIsFocusOnTopOfScreen(true);
} else {
updateIsFocusOnTopOfScreen(false);
}
After Identifying user is on top of the screen use panResponder to the flatlist/sectionList -> this is to identify the user is pulling the screen to bottom based on the this.pan.y._value increasing call your custom onRefresh method
const mover = Animated.event([null, { dx: this.pan.x, dy: this.pan.y }]);
onPanResponderMove: (e, gestureState) => {
mover(e, gestureState);
this.customRefreshControl(this.pan.y._value);
},