LEKCJA 12 - REACT NATIVE (p) - photos /updated 17.12/

LEKCJA 12 - REACT NATIVE (p) - photos /updated 17.12/
ukryj menu
SPEC
aktualizacja: 2021-12-17 12:05:04


Uwaga: Dzisiaj była aktualizacja Expo
Proszę o :
- usuniecie poprzedniego expo-cli z %AppData%
- ponowne zainstalowanie expo-cli 
- oraz aktualizację na telefonie Expo do wersji 2.23.2
- na koniec tworzymy nową aplikację



1. nawigacja typu Stack


UWAGA: poniższe moduły zainstaluj po kolei w folderze aplikacji, za pomocą CMD:


npm install @react-navigation/nativekopiuj
..\expo install react-native-screens react-native-safe-area-contextkopiuj
npm install @react-navigation/native-stackkopiuj

2. testowa aplikacja z użyciem nawigacji typu stack


w pliku App.js wstaw tylko:

import * as React from 'react';
import { View, Text } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';kopiuj

import Screen1 from "./components/Screen1"
import Screen2 from "./components/Screen2"kopiuj

const Stack = createNativeStackNavigator();

function App() {
  return (
        <NavigationContainer>
            <Stack.Navigator>
                <Stack.Screen name="s1" component={Screen1}  />
                <Stack.Screen name="s2" component={Screen2}  />               
            </Stack.Navigator>
        </NavigationContainer>
  );
}

export default App;
kopiuj


zaimportuj i dodaj testowy natywny Button w klasach ekranów Screen1.js, Screen2.js
przenoszący pomiędzy tymi dwoma ekranami

<Button
   title="go to screen2"
   onPress={() => this.props.navigation.navigate("s2")}
/>kopiuj



3. przekazanie obiektu z informacjami pomiędzy ekranami w nawigacji Stack


klik w ekranie s1

this.props.navigation.navigate("s2", {a: 1,b: 2})kopiuj


odbiór w renderze ekranu s2


console.log(this.props.route.params.a)
console.log(this.props.route.params.b)kopiuj


można przekazywać dane i funkcje


4. opcje wyglądu ekranu

wszystko ustalamy w pliku App dla danego ekranu
możemy pokazać lub ukryć header, zmienić jego kolorystykę
działa to podobnie jak w nawigacjach typu Tab i Drawer

<Stack.Screen
   name="s1"
   component={Screen1}
   options={{
      title: 'title',
      headerStyle: {
         backgroundColor: '#ff0000',
      },
      headerTintColor: '#ffffff',
      headerTitleStyle: {
         fontWeight: 'bold',
      },
}} />kopiuj


więcej w dokumentacji, np ukrycie headera

options={{
      ...
      headerShown: false
      ...
}}
kopiuj





5. MediaLibrary - dostęp do plików w galerii



zainstaluj w folderze swojej aplikacji poniższe moduły

..\expo install expo-media-library
..\expo install expo-sharingkopiuj



6. ekran galerii - wymiary 

- pobranie wymiarów ekranu, jeśli potrzebne, np do określenia wielkości zdjęcia, fonta, etc

import { Dimensions } from "react-native";kopiuj

sprawdzamy je w dowolnej funkcji

Dimensions.get("window").width
Dimensions.get("window").height
kopiuj

permissions dla pobierania plików z galerii

w componentDidMount()

let { status } = await MediaLibrary.requestPermissionsAsync();
if (status !== 'granted') {
    alert('brak uprawnień do czytania image-ów z galerii')
}kopiuj


pobranie zdjęć (lub innych assetów) z urządzenia

import

import * as MediaLibrary from "expo-media-library";kopiuj

działanie

let obj = await MediaLibrary.getAssetsAsync({
    first: 100,           // ilość pobranych assetów
    mediaType: 'photo'    // typ pobieranych danych, photo jest domyślne
})

alert(JSON.stringify(obj.assets, null, 4))kopiuj




FlatList - zmienna ilość kolumn, sterowana state-m (przełącznik lista / tabela)


<FlatList
    numColumns={this.state.numColumns}
    key={this.state.numColumns}
/>kopiuj


dokumentacja

https://docs.expo.io/versions/latest/sdk/media-library


7. komponent FotoItem

wykonujemy w osobnym pliku FotoItem.js

wielkość obrazka zmienia się w zależności od wybranej opcji grid / list w nadrzędnym komponencie


<Image
    style={{
        width: width_z_props,
        height: height_z_props,
        
    }}
    source={{ uri: uri_obrazka_przekazane_z_gallery }}
/>kopiuj


8. komponent BigPhoto

import

import * as MediaLibrary from "expo-media-library";kopiuj

usuwanie zdjęcia jak poprzednio w galerii



await MediaLibrary.deleteAssetsAsync("jednoelementowa_tablica_ids_zdjęć_do_usunięcia");kopiuj



powrót na poprzedni ekran

this.props.navigation.goBack();kopiuj

ustawienia Image na cały dostępny obszar ekranu

<Image
    resizeMode={'cover'}
    style={{ width: "100%", height: "100%" }}
    source={{ uri: uri_z_props }}
/>kopiuj


9. Sharing

dokumentacja

https://docs.expo.io/versions/latest/sdk/sharing/

10. Problem z usuwaniem zdjęć - Android 11

Najprościej ograniczyć wyświetlanie do zdjęć z tego właśnie folderu (DCIM):

let album = await MediaLibrary.getAlbumAsync("DCIM")

let photos = await MediaLibrary.getAssetsAsync({
            album:album,
            first: 20,
            mediaType: ['photo'],
})

można też zapisywać zdjęcia we stworzonym przez siebie folderze:

https://docs.expo.dev/versions/v43.0.0/sdk/media-library/#medialibrarycreatealbumasyncalbumname-asset-copyasset

11. konstrukcja aplikacji, komponenty


Main - ekran główny(przejście do grida galerii)
Gallery - przełączanie grid / list ze zdjęciami,

FotoItem - element grida / listy

BigPhoto

    - wyświetlenie dużego podglądu zdjęcia
    - usunięcie tego zdjęcia
    - od razu odświeżenie listy zdjęć w galerii
    - sharing zdjęcia