Przejdź do treści głównej
Wersja: 0.79

Obrazy

Nieoficjalne Tłumaczenie Beta

Ta strona została przetłumaczona przez PageTurner AI (beta). Nie jest oficjalnie zatwierdzona przez projekt. Znalazłeś błąd? Zgłoś problem →

Zasoby statycznych obrazów

React Native zapewnia ujednolicony sposób zarządzania obrazami i innymi zasobami multimedialnymi w aplikacjach na Androida i iOS. Aby dodać statyczny obraz do aplikacji, umieść go w drzewie kodu źródłowego i odwołaj się w ten sposób:

tsx
<Image source={require('./my-icon.png')} />

Nazwa obrazu jest rozwiązywana tak samo jak moduły JS. W powyższym przykładzie bundler będzie szukał pliku my-icon.png w tym samym folderze co komponent, który go wymaga.

Możesz użyć sufiksów @2x i @3x aby dostarczyć obrazy dla różnych gęstości ekranu. Jeśli masz następującą strukturę plików:

.
├── button.js
└── img
├── check.png
├── check@2x.png
└── check@3x.png

...a kod w button.js zawiera:

tsx
<Image source={require('./img/check.png')} />

...bundler dołączy i udostępni obraz odpowiadający gęstości ekranu urządzenia. Na przykład check@2x.png zostanie użyty na iPhone 7, podczas gdy check@3x.png na iPhone 7 Plus lub Nexus 5. Jeśli nie ma obrazu pasującego do gęstości ekranu, zostanie wybrana najbliższa dostępna opcja.

W systemie Windows może być konieczne ponowne uruchomienie bundlera po dodaniu nowych obrazów do projektu.

Oto korzyści, które zyskujesz:

  1. Ten sam system na Androida i iOS.

  2. Obrazy znajdują się w tym samym folderze co kod JavaScript. Komponenty są samodzielne.

  3. Brak globalnej przestrzeni nazw – nie musisz martwić się kolizjami nazw.

  4. Tylko faktycznie używane obrazy zostaną dołączone do aplikacji.

  5. Dodawanie i zmiana obrazów nie wymaga ponownej kompilacji aplikacji – możesz odświeżyć symulator jak zwykle.

  6. Bundler zna wymiary obrazów, nie ma potrzeby ich powielania w kodzie.

  7. Obrazy mogą być dystrybuowane przez pakiety npm.

Aby to działało, nazwa obrazu w require musi być znana statycznie.

tsx
// GOOD
<Image source={require('./my-icon.png')} />;

// BAD
const icon = this.props.active
? 'my-icon-active'
: 'my-icon-inactive';
<Image source={require('./' + icon + '.png')} />;

// GOOD
const icon = this.props.active
? require('./my-icon-active.png')
: require('./my-icon-inactive.png');
<Image source={icon} />;

Pamiętaj, że źródła obrazów wymagane w ten sposób zawierają informacje o rozmiarze (szerokość, wysokość). Jeśli potrzebujesz dynamicznie skalować obraz (np. przez flex), możesz potrzebować ręcznie ustawić {width: undefined, height: undefined} w atrybucie stylu.

Statyczne zasoby niebędące obrazami

Opisana składnia require może być również używana do statycznego dołączania plików audio, wideo lub dokumentów w projekcie. Obsługiwane są najpopularniejsze formaty, w tym .mp3, .wav, .mp4, .mov, .html i .pdf. Pełną listę znajdziesz w domyślnych ustawieniach bundlera.

Możesz dodać obsługę innych typów poprzez opcję resolvera assetExts w konfiguracji Metro.

Ograniczeniem jest to, że filmy wideo muszą używać pozycjonowania absolutnego zamiast flexGrow, ponieważ informacje o rozmiarze nie są obecnie przekazywane dla zasobów niebędących obrazami. To ograniczenie nie występuje dla filmów dodanych bezpośrednio w Xcode lub folderze Assets dla Androida.

Obrazy z zasobów aplikacji hybrydowej

Jeśli tworzysz aplikację hybrydową (część interfejsów w React Native, część w kodzie platformy), nadal możesz używać obrazów już dołączonych do aplikacji.

Dla obrazów dodanych przez katalog zasobów Xcode lub w folderze drawable Androida używaj nazwy obrazu bez rozszerzenia:

tsx
<Image
source={{uri: 'app_icon'}}
style={{width: 40, height: 40}}
/>

Dla obrazów w folderze assets Androida użyj schematu asset:/:

tsx
<Image
source={{uri: 'asset:/app_icon.png'}}
style={{width: 40, height: 40}}
/>

Te podejścia nie zapewniają kontroli bezpieczeństwa. To twoja odpowiedzialność, aby zapewnić dostępność tych obrazów w aplikacji. Musisz też ręcznie określać wymiary obrazów.

Obrazy sieciowe

Wiele obrazów wyświetlanych w aplikacji nie będzie dostępnych podczas kompilacji lub będziesz chciał ładować je dynamicznie, aby zmniejszyć rozmiar pliku binarnego. W przeciwieństwie do zasobów statycznych, musisz ręcznie określić wymiary obrazu. Zaleca się również używanie protokołu https, aby spełnić wymagania App Transport Security na iOS.

tsx
// GOOD
<Image source={{uri: 'https://reactjs.org/logo-og.png'}}
style={{width: 400, height: 400}} />

// BAD
<Image source={{uri: 'https://reactjs.org/logo-og.png'}} />

Żądania sieciowe dla obrazów

Jeśli chcesz ustawić dodatkowe elementy jak metodę HTTP, nagłówki lub treść żądania wraz z obrazem, możesz to zrobić definiując te właściwości w obiekcie źródłowym:

tsx
<Image
source={{
uri: 'https://reactjs.org/logo-og.png',
method: 'POST',
headers: {
Pragma: 'no-cache',
},
body: 'Your Body goes here',
}}
style={{width: 400, height: 400}}
/>

Obrazy z danymi URI

Czasami możesz otrzymać zakodowane dane obrazu z wywołania REST API. Możesz użyć schematu URI 'data:' do wykorzystania tych obrazów. Podobnie jak w przypadku zasobów sieciowych, musisz ręcznie określić wymiary obrazu.

informacja

Jest to zalecane tylko dla bardzo małych i dynamicznych obrazów, takich jak ikony na liście z bazy danych.

tsx
// include at least width and height!
<Image
style={{
width: 51,
height: 51,
resizeMode: 'contain',
}}
source={{
uri: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADMAAAAzCAYAAAA6oTAqAAAAEXRFWHRTb2Z0d2FyZQBwbmdjcnVzaEB1SfMAAABQSURBVGje7dSxCQBACARB+2/ab8BEeQNhFi6WSYzYLYudDQYGBgYGBgYGBgYGBgYGBgZmcvDqYGBgmhivGQYGBgYGBgYGBgYGBgYGBgbmQw+P/eMrC5UTVAAAAABJRU5ErkJggg==',
}}
/>

Kontrola pamięci podręcznej

W niektórych przypadkach możesz chcieć wyświetlić obraz tylko jeśli znajduje się już w lokalnej pamięci podręcznej, np. zastępczy obraz o niskiej rozdzielczości aż będzie dostępny wyższy. W innych sytuacjach możesz nie przejmować się aktualnością obrazu i wyświetlić przestarzały, aby oszczędzić przepustowość. Właściwość cache źródła daje kontrolę nad interakcją warstwy sieciowej z pamięcią podręczną.

  • default: Użyj domyślnej strategii natywnej platformy.

  • reload: Dane dla adresu URL zostaną załadowane z oryginalnego źródła. Żadne istniejące dane z pamięci podręcznej nie powinny być użyte do obsłużenia żądania załadowania adresu URL.

  • force-cache: Istniejące dane z pamięci podręcznej zostaną użyte do obsłużenia żądania, niezależnie od ich wieku lub daty wygaśnięcia. Jeśli w pamięci podręcznej nie ma danych odpowiadających żądaniu, dane zostaną załadowane z oryginalnego źródła.

  • only-if-cached: Istniejące dane z pamięci podręcznej zostaną użyte do obsłużenia żądania, niezależnie od ich wieku lub daty wygaśnięcia. Jeśli w pamięci podręcznej nie ma danych odpowiadających żądaniu załadowania adresu URL, nie podejmuje się próby załadowania danych z oryginalnego źródła, a ładowanie jest uznawane za nieudane.

tsx
<Image
source={{
uri: 'https://reactjs.org/logo-og.png',
cache: 'only-if-cached',
}}
style={{width: 400, height: 400}}
/>

Obrazy z lokalnego systemu plików

Zobacz CameraRoll jako przykład użycia lokalnych zasobów znajdujących się poza Images.xcassets.

Zasoby drawable

Android obsługuje ładowanie zasobów drawable poprzez pliki typu xml. Oznacza to, że możesz używać wektorowych drawable do renderowania ikon lub kształtów drawable do rysowania kształtów! Możesz importować i używać tych typów zasobów tak samo jak innych zasobów statycznych lub hybrydowych. Wymiary obrazu musisz określić ręcznie.

Dla statycznych drawable znajdujących się obok kodu JS, użyj składni require lub import (oba działają tak samo):

tsx
<Image
source={require('./img/my_icon.xml')}
style={{width: 40, height: 40}}
/>

Dla drawable w folderze Android drawable (tj. res/drawable), użyj nazwy zasobu bez rozszerzenia:

tsx
<Image
source={{uri: 'my_icon'}}
style={{width: 40, height: 40}}
/>

Kluczowa różnica między zasobami drawable a innymi typami obrazów polega na tym, że zasób musi być referencjonowany podczas kompilacji aplikacji Android, ponieważ Android musi uruchomić Android Asset Packaging Tool (AAPT) do pakowania zasobu. Binarny XML, format tworzony przez AAPT, nie może być ładowany przez sieć w Metro. Jeśli zmienisz katalog lub nazwę zasobu, będziesz musiał za każdym razem przebudować aplikację Android.

Tworzenie zasobów drawable w formacie XML

Android zapewnia kompleksową dokumentację dotyczącą każdego obsługiwanego typu zasobów rysunkowych w przewodniku Zasoby rysunkowe, wraz z przykładami surowych plików XML. Możesz wykorzystać narzędzia z Android Studio, takie jak Vector Asset Studio, do tworzenia wektorowych zasobów rysunkowych z plików Scalable Vector Graphic (SVG) i Adobe Photoshop Document (PSD).

informacja

Powinieneś unikać odwołań do innych zasobów w tworzonym pliku XML, jeśli chcesz traktować go jako statyczny zasób obrazu (tj. używając instrukcji import lub require). Jeśli chcesz wykorzystać odwołania do innych zasobów rysunkowych lub atrybutów, takich jak listy stanów kolorów czy zasoby wymiarów, powinieneś dołączyć swój zasób rysunkowy jako zasób hybrydowy i importować go po nazwie.

Najlepsze zdjęcie z rolki aparatu

iOS zapisuje wiele rozmiarów tego samego zdjęcia w Twojej rolce aparatu. Ze względów wydajnościowych kluczowe jest wybranie rozmiaru możliwie najbliższego docelowemu. Nie chciałbyś używać pełnej jakości obrazu 3264x2448 jako źródła przy wyświetlaniu miniatury 200x200. Jeśli istnieje dokładne dopasowanie, React Native wybierze je; w przeciwnym razie użyje pierwszego dostępnego rozmiaru co najmniej 50% większego, aby uniknąć rozmycia przy zmianie rozmiaru. Wszystko to dzieje się domyślnie, więc nie musisz pisać żmudnego (i podatnego na błędy) kodu.

Dlaczego nie automatycznie dopasowywać wszystkiego?

W przeglądarce jeśli nie podasz rozmiaru obrazu, przeglądarka wyrenderuje element 0x0, pobierze obraz, a następnie wyświetli go z właściwymi wymiarami. Głównym problemem tego zachowania jest "skakanie" interfejsu podczas ładowania obrazów, co tworzy złe wrażenia użytkownika. Zjawisko to nazywa się Cumulative Layout Shift.

W React Native celowo nie zaimplementowano tego zachowania. Wymaga to od programisty dodatkowej pracy (znajomość wymiarów lub proporcji zdalnego obrazu z wyprzedzeniem), ale wierzymy, że prowadzi to do lepszych doświadczeń użytkownika. Obrazy statyczne ładowane z pakietu aplikacji przez składnię require('./my-icon.png') mogą mieć automatycznie dobierany rozmiar, ponieważ ich wymiary są dostępne natychmiast podczas montowania.

Na przykład wynik require('./my-icon.png') może być:

tsx
{"__packager_asset":true,"uri":"my-icon.png","width":591,"height":573}

Źródło jako obiekt

W React Native ciekawą decyzją jest nazwanie atrybutu src jako source, który przyjmuje nie ciąg znaków, ale obiekt z atrybutem uri.

tsx
<Image source={{uri: 'something.jpg'}} />

Po stronie infrastruktury pozwala to na dołączanie metadanych do tego obiektu. Na przykład przy użyciu require('./my-icon.png') dodajemy informacje o jego rzeczywistej lokalizacji i rozmiarze (nie polegaj na tym, może się zmienić!). To także zabezpieczenie na przyszłość – np. jeśli zechcemy wspierać sprite'y, zamiast zwracać {uri: ...}, możemy zwrócić {uri: ..., crop: {left: 10, top: 50, width: 20, height: 40}}, przejrzyście wspierając sprite'y we wszystkich istniejących miejscach wywołań.

Po stronie użytkownika pozwala to na dodawanie przydatnych atrybutów, takich jak wymiary obrazu do obliczenia docelowego rozmiaru wyświetlania. Możesz swobodnie używać tej struktury do przechowywania dodatkowych informacji o obrazie.

Obraz tła poprzez zagnieżdżanie

Częstym zapytaniem od programistów pochodzących ze środowiska webowego jest funkcjonalność background-image. Aby zaimplementować ten przypadek użycia, możesz wykorzystać komponent <ImageBackground>, który przyjmuje te same właściwości (props) co <Image>, i dodać dowolne elementy potomne, które chcesz umieścić na wierzchu tego tła.

W niektórych przypadkach możesz nie chcieć używać <ImageBackground>, ponieważ jego implementacja jest podstawowa. Zapoznaj się z dokumentacją <ImageBackground>, aby uzyskać więcej informacji, i utwórz własny komponent, gdy zajdzie potrzeba.

tsx
return (
<ImageBackground source={...} style={{width: '100%', height: '100%'}}>
<Text>Inside</Text>
</ImageBackground>
);

Pamiętaj, że musisz określić atrybuty stylu dotyczące szerokości (width) i wysokości (height).

Style zaokrąglenia narożników w iOS

Pamiętaj, że następujące właściwości stylu zaokrąglenia narożników mogą być ignorowane przez komponent obrazu w iOS:

  • borderTopLeftRadius

  • borderTopRightRadius

  • borderBottomLeftRadius

  • borderBottomRightRadius

Dekodowanie poza głównym wątkiem

Dekodowanie obrazów może trwać dłużej niż czas przeznaczony na jedną klatkę animacji. To jedna z głównych przyczyn opuszczania klatek na stronach internetowych, gdzie dekodowanie odbywa się w głównym wątku. W React Native dekodowanie obrazów następuje w osobnym wątku. W praktyce, ponieważ i tak musisz obsłużyć sytuację, gdy obraz nie został jeszcze pobrany, wyświetlanie zastępczego obrazu przez kilka dodatkowych klatek podczas dekodowania nie wymaga zmian w kodzie.

Konfigurowanie limitów pamięci podręcznej obrazów w iOS

W systemie iOS udostępniamy interfejs API do nadpisania domyślnych limitów pamięci podręcznej obrazów w React Native. Należy go wywołać w natywnym kodzie AppDelegate (np. w metodzie didFinishLaunchingWithOptions).

objectivec
RCTSetImageCacheLimits(4*1024*1024, 200*1024*1024);

Parametry:

NameTypeRequiredDescription
imageSizeLimitnumberYesImage cache size limit.
totalCostLimitnumberYesTotal cache cost limit.

W powyższym przykładzie limit rozmiaru pojedynczego obrazu ustawiono na 4 MB, a całkowity limit kosztu na 200 MB.