11/**
2+ * Created by Rabbit on 2019-08-12.
23 * @flow
3- * Created by Rabbit on 2018/4/26.
44 */
55
6- import React from 'react' ;
6+ import React , { useState } from 'react' ;
7+ // import PropTypes, { any } from 'prop-types';
8+ import { Animated , Image as ImageNative , StyleSheet , View , Platform } from 'react-native' ;
9+ import FastImage , { ImageStyle } from 'react-native-fast-image' ;
710
8- import FastImage from 'react-native-fast-image' ;
9- import { Image , StyleSheet , View , Animated } from 'react-native' ;
10- import { observer } from 'mobx-react' ;
11- // import {observable, action} from 'mobx';
12-
13- type Props = {
14- ...Image . propTypes
11+ type ImageType = {
12+ placeholderStyle : any ,
13+ PlaceholderContent : any ,
14+ containerStyle : any ,
15+ style : any ,
16+ ImageComponent : any ,
17+ children : any ,
18+ ...ImageStyle
1519} ;
1620
17- @observer
18- class CustomImage extends React . Component < Props , any > {
19- constructor ( props : Props ) {
20- super ( props ) ;
21- this . state = {
22- imageLoading : true
23- } ;
24- }
25-
26- imageLoadError ( ) {
27- console . log ( 'onError' ) ;
28- // this.imageLoadedError = true;
29- this . setState ( { imageLoading : false } ) ;
30-
31- this . props . onError && this . props . onError ( ) ;
32- }
21+ const CustomImage = ( {
22+ placeholderStyle,
23+ PlaceholderContent,
24+ containerStyle,
25+ style,
26+ ImageComponent,
27+ children,
28+ ...attributes
29+ } : ImageType ) => {
30+ const [ placeholderOpacity ] = useState ( new Animated . Value ( 1 ) ) ;
31+ const [ imageError , setImageError ] = useState ( false ) ;
32+ const hasImage = typeof attributes . source !== 'undefined' ;
3333
34- onLoad = ( ) => {
34+ const onLoad = ( ) => {
35+ setImageError ( false ) ;
3536 const minimumWait = 100 ;
3637 const staggerNonce = 200 * Math . random ( ) ;
3738
@@ -40,41 +41,90 @@ class CustomImage extends React.Component<Props, any> {
4041 Animated . timing ( placeholderOpacity , {
4142 toValue : 0 ,
4243 duration : 350 ,
43- useNativeDriver : Android ? false : true ,
44+ useNativeDriver : Platform . OS !== 'android'
4445 } ) . start ( ) ;
4546 } ,
4647 Platform . OS === 'android' ? 0 : Math . floor ( minimumWait + staggerNonce )
4748 ) ;
4849 } ;
4950
50- render ( ) {
51- let { source } = this . props ;
52- const { style , resizeMode } = this . props ;
51+ const onError = ( ) => {
52+ setImageError ( true ) ;
53+ } ;
54+
55+ return (
56+ < View accessibilityIgnoresInvertColors = { true } style = { StyleSheet . flatten ( [ styles . container , containerStyle ] ) } >
57+ < ImageComponent
58+ { ...attributes }
59+ onLoad = { onLoad }
60+ onError = { onError }
61+ style = { [
62+ StyleSheet . absoluteFill ,
63+ {
64+ width : style . width ,
65+ height : style . height
66+ }
67+ ] }
68+ testID = "RNE__Image"
69+ />
70+
71+ < Animated . View
72+ pointerEvents = { hasImage ? 'none' : 'auto' }
73+ accessibilityElementsHidden = { hasImage }
74+ importantForAccessibility = { hasImage ? 'no-hide-descendants' : 'yes' }
75+ style = { [
76+ styles . placeholderContainer ,
77+ {
78+ opacity : hasImage ? placeholderOpacity : 1
79+ }
80+ ] }
81+ >
82+ < View
83+ testID = "RNE__Image__placeholder"
84+ style = { StyleSheet . flatten ( [ style , styles . placeholder , placeholderStyle ] ) }
85+ >
86+ { PlaceholderContent }
87+ </ View >
88+ </ Animated . View >
5389
54- source = this . state . imageLoading
55- ? source
56- : {
57- uri : 'https://reactnativecode.com/wp-content/uploads/2018/01/Error_Img.png'
58- } ;
59- return (
60- < View style = { [ styles . customImageView ] } >
90+ < View style = { style } > { children } </ View >
91+
92+ { imageError && (
6193 < FastImage
62- { ...this . props }
63- style = { style }
64- source = { source }
65- resizeMode = { this . state . imageLoading ? resizeMode : 'contain' }
66- onError = { this . imageLoadError . bind ( this ) }
94+ source = { { uri : 'https://reactnativecode.com/wp-content/uploads/2018/01/Error_Img.png' } }
95+ style = { [ containerStyle , style ] }
6796 />
68- </ View >
69- ) ;
70- }
71- }
97+ ) }
98+ </ View >
99+ ) ;
100+ } ;
72101
73- const styles = StyleSheet . create ( {
74- customImageView : {
75- flex : 1 ,
102+ const styles = {
103+ container : {
104+ backgroundColor : 'transparent' ,
105+ position : 'relative'
106+ } ,
107+ placeholderContainer : {
108+ ...StyleSheet . absoluteFillObject
109+ } ,
110+ placeholder : {
111+ backgroundColor : '#bdbdbd' ,
112+ alignItems : 'center' ,
76113 justifyContent : 'center'
77114 }
78- } ) ;
115+ } ;
116+
117+ // CustomImage.propTypes = {
118+ // ...ImageStyle,
119+ // ImageComponent: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
120+ // PlaceholderContent: any,
121+ // containerStyle: any,
122+ // placeholderStyle: ImageNative.propTypes.style
123+ // };
124+
125+ CustomImage . defaultProps = {
126+ ImageComponent : FastImage ,
127+ style : { }
128+ } ;
79129
80130export default CustomImage ;
0 commit comments