ukryj menu
SPEC
aktualizacja: 2022-02-04 11:07:51
0. Opis
Aplikacja trzyekranowa
Aplikacja pozwalająca na pobranie i zapis danych geolokacyjnych
oraz wyświetlenie ich na mapie
Aplikacja wykonana za pomocą komponentów funkcyjnych, patrz lekcja 16
1. film na YT obrazujący działanie aplikacji
https://youtu.be/1VMjpZMr4PIkopiuj
2. Activity Indicator
https://docs.expo.dev/versions/latest/react-native/activityindicator/
ActivityIndicator jest widoczny w zależności od wartości jakiejś zmiennej, w tym wypadku zmiennej isLoading
Pokazuje się w momencie naciśnięcia przycisku "zapisz pozycję"
Ukrywa się w momencie pobrania pozycji przez geolokator
schemat pracy
const [isLoading, setIsLoading] = useState(false);
...
setIsLoading(true); // gdzieś w aplikacji
...
setIsLoading(false); // gdzieś w aplikacji
...
return (
<ActivityIndicator size="large" color="#0000ff" animating={isLoading} />
)kopiuj
...
setIsLoading(true); // gdzieś w aplikacji
...
setIsLoading(false); // gdzieś w aplikacji
...
return (
<ActivityIndicator size="large" color="#0000ff" animating={isLoading} />
)kopiuj
3. Customowy font wykorzystujący hook useFonts()
przykład działania
import { useFonts } from "expo-font";
import Montserrat from "../assets/fonts/Montserrat.ttf";
import Montserrat_bold from "../assets/fonts/Montserrat-Bold.ttf";
const [fontLoaded] = useFonts({
Montserrat,
Montserrat_bold,
});
return fontLoaded ? (
<View>
<Text style={{ fontFamily: "Montserrat" }}>Some text</Text>
</View>
) : null;
kopiuj
import Montserrat from "../assets/fonts/Montserrat.ttf";
import Montserrat_bold from "../assets/fonts/Montserrat-Bold.ttf";
const [fontLoaded] = useFonts({
Montserrat,
Montserrat_bold,
});
return fontLoaded ? (
<View>
<Text style={{ fontFamily: "Montserrat" }}>Some text</Text>
</View>
) : null;
kopiuj
4. Geolokacja await async
import * as Location from "expo-location";
callback hooka efektu NIE może być asynchroniczny, ale można ten problem obejść tak
useEffect(() => {
// Jednocześnie deklarujemy i wykonujemy anonimową funkcję asynchroniczną
(async () => {
... // Tutaj można używać await
})();
}, []);kopiuj
// Jednocześnie deklarujemy i wykonujemy anonimową funkcję asynchroniczną
(async () => {
... // Tutaj można używać await
})();
}, []);kopiuj
przydzielenie uprawnień do korzystania z geolokacji w urządzeniu - confirm
useEffect(() => {
(async () => {
const { status } = await Location.requestForegroundPermissionsAsync();
if (status !== "granted") {
alert("Permission to access location was denied");
}
})();
}, []);kopiuj
(async () => {
const { status } = await Location.requestForegroundPermissionsAsync();
if (status !== "granted") {
alert("Permission to access location was denied");
}
})();
}, []);kopiuj
pobranie bieżącej lokalizacji po kliku butona
const getPosition = async () => {
const location = await Location.getCurrentPositionAsync();
alert(JSON.stringify(pos, null, 4));
};
kopiuj
Dokumentacja
https://docs.expo.dev/versions/v44.0.0/sdk/location/
4. AsyncStorage, async, await - trwały zapis danych w urządzeniu
AsyncStorage to trochę "lepsza" wersja SecureStore, posiada gotowy mechanizm
odczytu wszystkich kluczy
Wbudowany w React Native AsyncStorage został zdeprecjonowany dlatego polecam użyć paczki community
https://github.com/react-native-async-storage/async-storage
npm install @react-native-async-storage/async-storagekopiuj
import
import AsyncStorage from "@react-native-async-storage/async-storage";kopiuj
zapis jednej wartości
const setData = async () => {
//await AsyncStorage.setItem('key1', 'value1');
await AsyncStorage.setItem(
"key" + Math.round(Math.random() * 100),
"value" + Math.random()
);
};kopiuj
//await AsyncStorage.setItem('key1', 'value1');
await AsyncStorage.setItem(
"key" + Math.round(Math.random() * 100),
"value" + Math.random()
);
};kopiuj
odczyt jednej wartości
const getData = async () => {
const val = await AsyncStorage.getItem("key1");
console.log(val);
};kopiuj
const val = await AsyncStorage.getItem("key1");
console.log(val);
};kopiuj
odczyt wszystkich kluczy
const getAllData = async () => {
const keys = await AsyncStorage.getAllKeys();
console.log("keys", keys);
const stores = await AsyncStorage.multiGet(keys);
console.log("stores", stores);
const maps = stores.map((result, i, store) => {
const key = store[i][0];
const value = store[i][1];
console.log(key, value);
});
};kopiuj
const keys = await AsyncStorage.getAllKeys();
console.log("keys", keys);
const stores = await AsyncStorage.multiGet(keys);
console.log("stores", stores);
const maps = stores.map((result, i, store) => {
const key = store[i][0];
const value = store[i][1];
console.log(key, value);
});
};kopiuj
6. mapy
uwaga:
poniższy wyjątkowo prosty sposób renderowania map google, jest dostępny
wyłącznie w aplikacji Expo.
w realnej aplikacji androida należy
najpierw zdobyć klucz do api google a dalsze działania są zależne od
urządzenia
..\expo install react-native-mapskopiuj
https://docs.expo.io/versions/latest/sdk/map-view/
import
import MapView, { Marker } from "react-native-maps";kopiuj
render
<MapView
style={{ flex: 1 }}
initialRegion={{
latitude: 50.111,
longitude: 20.111,
latitudeDelta: 0.001,
longitudeDelta: 0.001,
}}
>
<Marker
coordinate={{
latitude: 50.111,
longitude: 20.111,
}}
title={"pos"}
description={"opis"}
/>
</MapView>kopiuj
7. komponent Switch
import { Switch } from "react-native";
const [switchState, setSwitchState] = useState(false);
const onSwitch = (enabled) => {
setSwitchState(enabled);
};
<Switch
trackColor={{ true: "green", false: "lightgray" }}
thumbColor={switchState ? "green" : "white"}
value={switchState}
onValueChange={onSwitch}
/>kopiuj
8. konstrukcja aplikacji, komponenty
- Main - ekran główny (przejście do listy, koniecznie custom font)
- List - lista trwale zapisanych lokalizacji (FlatList), --- możliwość dodania kolejnych i usunięcia wszystkich,
--- możliwość zaznaczenia pozycji do wyświetlenia na mapie (Switch)--- dodatkowy Switch zaznaczający/odznaczający wszystkie pozycje na raz
- ListItem
- element listy
- Map -
mapa - wyświetlenie wybranych pozycji w postaci markerów