Ответ 1
Image компонент теперь предоставляет статический метод для получения размера изображения. Например:
Image.getSize(myUri, (width, height) => {this.setState({width, height})});
Я хотел бы иметь возможность узнать фактический размер загруженного по сети изображения, которое было передано в <Image/>
Я пытался использовать onLayout
для определения размера (как взято здесь https://github.com/facebook/реагировать-родной/проблемы/858) но это, кажется, возвращает очищенный размер после того, как он уже был передан через механизм макета.
Я попытался заглянуть в onLoadStart, onLoad, onLoadEnd, onProgress, чтобы увидеть, есть ли какая-либо другая доступная информация, но, похоже, не может заставить ее работать. Я объявил их следующим образом:
onImageLoadStart: function(e){
console.log("onImageLoadStart");
},
onImageLoad: function(e){
console.log("onImageLoad");
},
onImageLoadEnd: function(e){
console.log("onImageLoadEnd");
},
onImageProgress: function(e){
console.log("onImageProgress");
},
onImageError: function(e){
console.log("onImageError");
},
render: function (e) {
return (
<Image
source={{uri: "http://adomain.com/myimageurl.jpg"}}
style={[this.props.style, this.state.style]}
onLayout={this.onImageLayout}
onLoadStart={(e) => {this.onImageLoadStart(e)}}
onLoad={(e) => {this.onImageLoad(e)}}
onLoadEnd={(e) => {this.onImageLoadEnd(e)}}
onProgress={(e) => {this.onImageProgress(e)}}
onError={(e) => {this.onImageError(e)}} />
);
}
Благодарю.
Image компонент теперь предоставляет статический метод для получения размера изображения. Например:
Image.getSize(myUri, (width, height) => {this.setState({width, height})});
Image.getSize(myUri, (width, height) => {this.setState({width, height});
Хорошо, я получил это работает. В настоящее время требуется некоторая модификация установки React-Native, поскольку она не поддерживается изначально.
Я следовал советам в этой теме, чтобы я смог это сделать. https://github.com/facebook/react-native/issues/494
В основном, измените файл RCTNetworkImageView.m: добавьте следующее в setImageURL
void (^loadImageEndHandler)(UIImage *image) = ^(UIImage *image) {
NSDictionary *event = @{
@"target": self.reactTag,
@"size": @{
@"height": @(image.size.height),
@"width": @(image.size.width)
}
};
[_eventDispatcher sendInputEventWithName:@"loaded" body:event];
};
Затем отредактируйте строку, которая обрабатывает завершение загрузки:
[self.layer removeAnimationForKey:@"contents"];
self.layer.contentsScale = image.scale;
self.layer.contents = (__bridge id)image.CGImage;
loadEndHandler();
замещать
loadEndHandler();
с
loadImageEndHandler(image);
Затем в React-Native у вас есть доступ к размеру через нативные события. данные из функции onLoaded
- обратите внимание, в документации в настоящее время говорится, что функция onLoad
но это неверно. Правильные функции следующие для v0.8.0:
onLoadStart
onLoadProgress
onLoaded
onLoadError
onLoadAbort
К ним можно получить доступ так:
onImageLoaded: function(data){
try{
console.log("image width:"+data.nativeEvents.size.width);
console.log("image height:"+data.nativeEvents.size.height);
}catch(e){
//error
}
},
...
render: function(){
return (
<View style={{width:1,height:1,overflow='hidden'}}>
<Image source={{uri: yourImageURL}} resizeMode='contain' onLoaded={this.onImageLoaded} style={{width:5000,height:5000}} />
</View>
);
}
Примечания к сведению:
Я установил большое окно изображения и установил его внутри оберточного элемента размером 1x1px, потому что изображение должно помещаться внутрь, если вы хотите получить значимые значения.
Режим изменения размера должен быть 'contain'
чтобы вы могли получить правильные размеры, в противном случае будет сообщено об ограниченном размере.
Размеры изображения масштабируются пропорционально масштабному коэффициенту устройства, например, изображение 200 * 200 на iPhone6 (не 6 плюс) будет отображаться как 100 * 100. Я предполагаю, что это также означает, что на iPhone6 plus он будет отображаться как 67 * 67, но я не проверял это.
Я еще не получил это, чтобы работать для файлов GIF, которые пересекают другой путь на стороне моста Obj-C. Я обновлю этот ответ, как только я это сделаю.
Я полагаю, что в данный момент существует PR для этого, но до тех пор, пока он не будет включен в ядро, это изменение будет необходимо вносить в реактивную установку каждый раз, когда вы обновляете/переустанавливаете.
Вы можете использовать метод resolveAssetSource из компонента Image:
import picture from 'pathToYourPicture';
const {width, height} = Image.resolveAssetSource(picture);
Пример TypeScript:
import {Image} from 'react-native';
export interface ISize {
width: number;
height: number;
}
function getImageSize(uri: string): Promise<ISize> {
const success = (resolve: (value?: ISize | PromiseLike<ISize>) => void) => (width: number, height: number) => {
resolve({
width,
height
});
};
const error = (reject: (reason?: any) => void) => (failure: Error) => {
reject(failure);
};
return new Promise<ISize>((resolve, reject) => {
Image.getSize(uri, success(resolve), error(reject));
});
}