개인노트-인강

개인노트 nomad React-Native 초급 #2 Weather App

roroism 2023. 1. 17. 20:07

[2021 update] weather app

 

export default function App() {
  return (
    <View style={styles.container}>
      <Text>Hello! I made a RN App</Text>
      <StatusBar style="auto" />
    </View>
  );
}

const styles = {
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  },
};

# 2.0 Snack

 

Snack

브라우저에서 React 어플리케이션을 만들 수 있게 해주는 온라인 코드에디터입니다.

 

Snack Expo
https://snack.expo.dev

 

 

# 2.1 The Rules of Native

## 개요

export default function App() {
  return (
    <View style={styles.container}>
      <Text>Hello! I made a RN App</Text>
      <StatusBar style="auto" />
    </View>
  );
}

1. View

View = Container

웹에서의 div 대신 View를 사용합니다.

 

2. Text

react native에 있는 모든 text는 text component에 들어가야합니다.

 

3. style

Web에서 사용하던 모든 css 속성을 사용할 수 있는 것은 아닙니다.

98%정도? 사용가능.

예) border 는 사용할 수 없음.

 

## StyleSheet.create({})

 

사용이유 : 자동완성 기능을 제공합니다.

 

코드 예

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  },
  text: {
    fontSize: 28,
    color: "red"
  }
});

객체를 만들어 스타일을 적용합니다.

스타일을 꼭 이 방식으로 만들지 않아도 되고, 직접 element에 style을 적용해도됩니다.

export default function App() {
  return (
    <View style={{
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  }}>
      <Text>Hello! I made a RN App</Text>
      <StatusBar style="auto" />
    </View>
  );
}

 

StyleSheet가 꼭 필요한 것은 아닙니다. 단순히 분리가 목적이라면 아래처럼 해도 적용됩니다.

하지만 css 속성 자동 완성이 지원되지 않습니다.

export default function App() {
  return (
    <View style={styles.container}>
      <Text>Hello! I made a RN App</Text>
      <StatusBar style="auto" />
    </View>
  );
}

const styles = {
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  },
};

 

StylesSheet.create는 단지 object일 뿐이지만 자동완성 기능을 제공합니다.

 

## status-bar

 

status-bar는 third-party 패키지입니다.

 

코드 예

import { StatusBar } from "expo-status-bar";
import { StyleSheet, Text, View } from "react-native";

export default function App() {
  return (
    <View style={styles.container}>
      <Text style={styles.text}>Hello! I made a RN App</Text>
      <StatusBar style="auto" />
    </View>
  );
}

StatusBar component는 시계, 배터리, Wi-Fi를 의미합니다.

이 component는 스마트폰의 상태바와 소통할 수 있는 방법일 뿐입니다.

실제로 렌더링에 보이지 않습니다.

 

# 2.2 React Native Packages

 

React Native 팀은 제일 중요한 몇몇의 컴포넌트들만 남겨서 규모를 줄였습니다.

모든 컴포넌트들을 유지 관리하기가 힘들었기 때문입니다.

줄이고 없어진 기능들은 모두 커뮤니티의 몫으로 맡겨졌습니다.

대표적으로 expo. expo에서 expo에서만든 컴포넌트와 api를 제공합니다.

 

# 2.3 Third Party Packages

 

## Component와 API의 차이점

 

Component는 화면에 렌더링할 항목.

API는 JavaScript 코드. JavaScript코드가 운영 체제와 소통합니다.

 

Component의 예

  return (
    <View style={styles.container}>
      <Text style={styles.text}>Hello! I made a RN App</Text>
      <StatusBar style="auto" />
    </View>
  );

API의 예

진동

 

 

## 참고 url

 

React Native Doc
https://reactnative.dev/docs/0.60/components-and-apis

React Native Directory
https://reactnative.directory/

Expo Doc
https://docs.expo.dev/versions/latest/

 

# 2.4 Layout System

 

React Native에서 레이아웃을 만들려면 Flexbox를 사용해야 합니다.

React Native의 Flexbox는 웹에서와 거의 같은 방식입니다.(공식문서)

https://reactnative.dev/docs/flexbox

Flexbox works the same way in React Native as it does in CSS on the web, with a few exceptions. The defaults are different, with flexDirection defaulting to column instead of row, alignContent defaulting to flex-start instead of stretch, flexShrink defaulting to 0 instead of 1, the flex parameter only supporting a single number.

React Native 에서는 display: block, display: inline-block, display: grid가 없습니다. 

Flexbox만 사용하면됩니다.

 

## Flexbox

 

1. 기본적으로 모든 View는 Flex Container입니다.

 

코드

export default function App() {
  return (
    <View style={{ flexDirection: "row" }}>
      <View
        style={{ width: 200, height: 200, backgroundColor: "orange" }}
      ></View>
      <View style={{ width: 200, height: 200, backgroundColor: "blue" }}></View>
      <View
        style={{ width: 200, height: 200, backgroundColor: "blueviolet" }}
      ></View>
    </View>
  );
}

화면

 

하지만 웹에서와 다른점은 flex Direction 의 기본값은 Column입니다. 그래서 row로 직접 지정해주어야 가로로 배치됩니다.

웹에서는 flex Direction의 기본값이 row이었습니다.

 

2. 

레이아웃에서는 width와 height를 사용하지 않습니다.(아이콘에서는 사용할 수 있지만..)

스마트폰의 화면에 따라 다르게 보이기 때문입니다.

 

flex 속성을 이용하여 비율로만 표현합니다.

코드

    <View style={{ flex: 1 }}>
      <View style={{ flex: 1, backgroundColor: "orange" }}></View>
      <View style={{ flex: 1, backgroundColor: "blue" }}></View>
      <View style={{ flex: 1, backgroundColor: "blueviolet" }}></View>
    </View>

화면

자식 View의 3개의 크기를 동일하게 조절한다는 의미입니다. 가운데 View만 flex 값을 1.5로 바꾼다면..

 

코드

    <View style={{ flex: 1 }}>
      <View style={{ flex: 1, backgroundColor: "orange" }}></View>
      <View style={{ flex: 1.5, backgroundColor: "blue" }}></View>
      <View style={{ flex: 1, backgroundColor: "blueviolet" }}></View>
    </View>

화면

가운데 View의 크기가 1.5배 만큼 커집니다.

 

기타 참고 : 가로 또는 세로로 화면을 넘어서 overflow된다고 웹처럼 scrollbar가 생기지 않습니다.

 

# 2.5 Styles

 

참고 : vsccode를 저장해도 스마트폰 expo앱에 반영이 되지 않는다면 console창에서 키보드 r를 눌러 refresh 합니다.

 

코드

import { StatusBar } from "expo-status-bar";
import { StyleSheet, Text, View } from "react-native";

export default function App() {
  return (
    <View style={styles.container}>
      <View style={styles.city}>
        <Text style={styles.cityName}>Seoul</Text>
      </View>
      <View style={styles.weather}>
        <View style={styles.day}>
          <Text style={styles.temp}>27</Text>
          <Text style={styles.description}>Sunny</Text>
        </View>
      </View>
      <StatusBar style="dark" />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "cyan",
  },
  city: {
    flex: 1.2,
    justifyContent: "center",
    alignItems: "center",
  },
  cityName: {
    fontSize: 68,
    fontWeight: "500",
  },
  weather: {
    flex: 3,
  },
  day: {
    flex: 1,
    alignItems: "center",
  },
  temp: {
    marginTop: 50,
    fontSize: 178,
  },
  description: {
    marginTop: -30,
    fontSize: 60,
  },
});

 

# 2.6 Styles part Two

 

React Native에서는 표시할 엘리먼트가 화면을 넘어가면 일반 웹페이지처럼 자동으로 스크롤을 생성하지 않습니다.

스크롤을 사용하려면 ScrollView 컴포넌트를 사용해야 합니다.

 

## ScrollView


ScrollView는 내부에 컴포넌트와 뷰들을 자식으로 담을 수 있는, 화면의 스크롤을 사용할 때 쓰는 컴포넌트입니다.
스크롤 방향은 horizontal을 통해 가로 또는 세로로 변경할 수 있습니다.

ScrollView에는 매우 많은 props들이 있습니다.
https://reactnative.dev/docs/scrollview

 

<ScrollView style={styles.weather}>
        <View style={styles.day}>
          <Text style={styles.temp}>27</Text>
          <Text style={styles.description}>Sunny</Text>
        </View>
        <View style={styles.day}>
          <Text style={styles.temp}>27</Text>
          <Text style={styles.description}>Sunny</Text>
        </View>
        <View style={styles.day}>
          <Text style={styles.temp}>27</Text>
          <Text style={styles.description}>Sunny</Text>
        </View>
        <View style={styles.day}>
          <Text style={styles.temp}>27</Text>
          <Text style={styles.description}>Sunny</Text>
        </View>
</ScrollView>

 

### 속성 : horizontal

 

horizontal 속성을 추가하면 컴포넌트들이 가로로 정렬되며 scroll이 가로로 생성됩니다.

 

<ScrollView horizontal style={styles.weather}>
        <View style={styles.day}>
          <Text style={styles.temp}>27</Text>
          <Text style={styles.description}>Sunny</Text>
        </View>
        <View style={styles.day}>
          <Text style={styles.temp}>27</Text>
          <Text style={styles.description}>Sunny</Text>
        </View>
        <View style={styles.day}>
          <Text style={styles.temp}>27</Text>
          <Text style={styles.description}>Sunny</Text>
        </View>
        <View style={styles.day}>
          <Text style={styles.temp}>27</Text>
          <Text style={styles.description}>Sunny</Text>
        </View>
</ScrollView>

하지만 위처럼 하면, styles.weather이 적용되지 않습니다.

 

### 속성 : contentContainerStyle

 

ScrollView에서 style을 적용하려면 속성 contentContainerStyle를 사용해야 합니다. (공식문서 참고)

 

      <ScrollView horizontal contentContainerStyle={styles.weather}>
        <View style={styles.day}>
          <Text style={styles.temp}>27</Text>
          <Text style={styles.description}>Sunny</Text>
        </View>
        <View style={styles.day}>
          <Text style={styles.temp}>27</Text>
          <Text style={styles.description}>Sunny</Text>
        </View>
        <View style={styles.day}>
          <Text style={styles.temp}>27</Text>
          <Text style={styles.description}>Sunny</Text>
        </View>
        <View style={styles.day}>
          <Text style={styles.temp}>27</Text>
          <Text style={styles.description}>Sunny</Text>
        </View>
</ScrollView>

하지만 이렇게 하면 스타일을 적용되지만 스타일 안의 스타일 속성 flex는 적용되지 않고, 가로로 스크롤이 되지 않습니다. 왜냐하면 ScrollView에는 Flex 사이즈를 줄 필요가 없기 때문입니다. ScrollView는 스크린보다 더 나아가 화면밖으로 나가기 때문입니다. Flex속성을 제거하면 가로로 스크롤이 정상 작동됩니다.

 

### 속성 : pagingEnabled

 

https://reactnative.dev/docs/scrollview#pagingenabled

true인 경우 스크롤할 때 스크롤 뷰 크기의 배수에서 스크롤 뷰가 중지됩니다. 수평 페이지 매김에 사용할 수 있습니다.

흔히 경험이 있는..스크롤을 일정 한계이상 넘겨야 다음 페이지로 넘어가게 만들어 줍니다. 각각의 페이지처럼 만들어 줍니다. 

 

### 속성 : showsHorizontalScrollIndicator

 

https://reactnative.dev/docs/scrollview#showshorizontalscrollindicator

true인 경우 가로 스크롤 표시기를 표시합니다.

 

### 속성 : indicatorStyle

 

ios만 사용가능.

https://reactnative.dev/docs/scrollview#indicatorstyle-ios

 

### 속성 : persistentScrollbar

 

Android만 사용가능.

scroll bar가 투명해지지 않도록 해줍니다.

 

관련 참고 속성 : showsHorizontalScrollIndicator

관련 참고 속성 : showsVerticalScrollIndicator

 

## Dimensions

 

https://reactnative.dev/docs/dimensions

import {Dimensions} from 'react-native';

const windowWidth = Dimensions.get('window').width;
const windowHeight = Dimensions.get('window').height;

//or
const { height, width } = Dimensions.get("window");

 

스마트폰 화면 크기값을 얻을 수 있습니다.

이제 ScrollView 안에 있는 컴포넌트들에 적용되어 있는(ScrollView 안에 들어가 있어서 더이상 작동되지 않는)  Flex속성 대신에 사용하여 한 화면에 하나의 Day 값만 나오게 하고, 다음 날짜 는 가로 스크롤을 통해 표시되게 할 수 있습니다.

 

적용 코드

import { StyleSheet, Text, View, ScrollView, Dimensions } from "react-native";

const { width: SCREEN_WIDTH } = Dimensions.get("window");

export default function App() {
//...
}

const styles = StyleSheet.create({
//...
  day: {
    width: SCREEN_WIDTH,
    alignItems: "center",
  },
  //...
//...
});

 

최종 적용 코드

import { StatusBar } from "expo-status-bar";
import { StyleSheet, Text, View, ScrollView, Dimensions } from "react-native";

const { width: SCREEN_WIDTH } = Dimensions.get("window");

export default function App() {
  return (
    <View style={styles.container}>
      <View style={styles.city}>
        <Text style={styles.cityName}>Seoul</Text>
      </View>
      <ScrollView
        horizontal
        pagingEnabled
        indicatorStyle="white"
        // showsHorizontalScrollIndicator={false}
        contentContainerStyle={styles.weather}
      >
        <View style={styles.day}>
          <Text style={styles.temp}>27</Text>
          <Text style={styles.description}>Sunny</Text>
        </View>
        <View style={styles.day}>
          <Text style={styles.temp}>27</Text>
          <Text style={styles.description}>Sunny</Text>
        </View>
        <View style={styles.day}>
          <Text style={styles.temp}>27</Text>
          <Text style={styles.description}>Sunny</Text>
        </View>
        <View style={styles.day}>
          <Text style={styles.temp}>27</Text>
          <Text style={styles.description}>Sunny</Text>
        </View>
      </ScrollView>
      <StatusBar style="dark" />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "cyan",
  },
  city: {
    flex: 1.2,
    justifyContent: "center",
    alignItems: "center",
  },
  cityName: {
    fontSize: 68,
    fontWeight: "500",
  },
  weather: {
    // backgroundColor: "blue",
    // flex: 3,
  },
  day: {
    width: SCREEN_WIDTH,
    // flex: 1,
    alignItems: "center",
  },
  temp: {
    marginTop: 50,
    fontSize: 178,
  },
  description: {
    marginTop: -30,
    fontSize: 60,
  },
});

 

# 2.7 Location

 

유저 위치 정보를 가져오는 방법을 알아보겠습니다.

 

## installation

 

expo install expo-location

cmd 창에 입력하여 설치합니다.

공식문서 : https://docs.expo.dev/versions/latest/sdk/location/

 

### 여러 메소드들

 

requestPermissionsAsync() : 유저 권한을 요청. 무조건 해야합니다. (Deprecated) 

    위 메소드 대신에 아래 메소드를 사용합니다.

    requestForegroundPermissionsAsync() : 앱이 실행되는 동안 사용자에게 위치에 대한 권한을 부여하도록 요청합니다.

    requestBackgroundPermissionsAsync() : 앱이 백그라운드에 있는 동안 사용자에게 위치에 대한 권한을 부여하도록 요청합니다.

getLastKnownPositionAsync() : 유저의 마지막 위치를 받을 수 있습니다.

getCurrentPositionAsync() : 유저의 현재 위치를 받을 수 있습니다.

watchPositionAsync() : 위치를 관찰합니다. 그래서 유저가 이동을 해도 따라가면서 위치를 알 수 있습니다.

geocodeAsync() : 주소를 받아서 위도와 경도로 변환해줍니다.

reverseGeocodeAsync(location) : 위도와 경도를 이 function에 주면 도시와 구역을 반환해줍니다.

startGeofencingAsync(taskName, regions) : 유저가 특정 지역을 벗어났을 때 알려줍니다. 그래서 유저가 그 지역에 있을 수 있도록 유도할 수 있습니다. 유저가 그 지역을 들어갔을 때나 나갔을 때 우리에게 말해줍니다.

 

## 1. 권한 요청

 

https://docs.expo.dev/versions/latest/sdk/location/

공식문서의 usage를 참고하여 코드를 가져옵니다.

 

import * as Location from "expo-location";

export default function App() {
  const [location, setLocation] = useState(null);
  const [ok, setOk] = useState(true);

  const ask = async () => {
    const { granted } = await Location.requestForegroundPermissionsAsync();
    if(!granted) {
      setOk(false);
    }
  };

  useEffect(() => {
    ask();
  }, []);

  return (
  //...

 

## 2. 위치 정보

 

getCurrentPosition의 옵션 중 LocationAccuracy는 위치의 정확도를 설정합니다.

공식문서 : https://docs.expo.dev/versions/latest/sdk/location/#accuracy

 

### useGoogleMaps api키가 필요한 경우

 

Google Maps Platform에서 Geocoding API를 만들어 key를 얻은 다음 Location.setGoogleApiKey(key)를 reverseGeocodeAsync보다 선행해주시면 됩니다. 결제절차가 끼어있는데 무료평가판을 사용하시면 됩니다.

 

Google Maps Platform : https://console.cloud.google.com/home

 

## 최종코드

import { StatusBar } from "expo-status-bar";
import { useEffect, useState } from "react";
import { StyleSheet, Text, View, ScrollView, Dimensions } from "react-native";
import * as Location from "expo-location";

const { width: SCREEN_WIDTH } = Dimensions.get("window");

export default function App() {
  const [city, setCity] = useState("Loading...");
  const [location, setLocation] = useState(null);
  const [ok, setOk] = useState(true);

  const ask = async () => {
    const { granted } = await Location.requestForegroundPermissionsAsync();
    if (!granted) {
      setOk(false);
    }
    const {
      coords: { latitude, longitude },
    } = await Location.getCurrentPositionAsync({ accuracy: 5 });
    const location = await Location.reverseGeocodeAsync(
      {
        latitude,
        longitude,
      },
      { useGoogleMaps: false }
    );
    setCity(location[0].city);
  };

  useEffect(() => {
    ask();
  }, []);

  return (
  //...

 

# 2.8 Weather

## OpenWeatherMap

 

openweather api를 활용하여 날씨정보를 가져옵니다.

 

### 참고 문서

 

OpenWeatherMap
https://openweathermap.org

 

API Key
https://home.openweathermap.org/api_keys

 

## ActivityIndicator

 

로딩중 아이콘  React Native 컴포넌트입니다.

공식문서 : https://reactnative.dev/docs/activityindicator

 

사용 예 

import React from 'react';
import {ActivityIndicator, StyleSheet, View} from 'react-native';

const App = () => (
  <View style={[styles.container, styles.horizontal]}>
    <ActivityIndicator />
    <ActivityIndicator size="large" />
    <ActivityIndicator size="small" color="#0000ff" />
    <ActivityIndicator size="large" color="#00ff00" />
  </View>
);

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
  },
  horizontal: {
    flexDirection: 'row',
    justifyContent: 'space-around',
    padding: 10,
  },
});

export default App;

 

## 날짜 변환

 

코드

new Date(day.dt * 1000).toString().substring(0, 10)

 

## api 데이터 가져오기

 

코드

const part = ["current", "minutely", "hourly", "daily", "alerts"];
const response = await fetch(
  `https://api.openweathermap.org/data/2.5/onecall?lat=${latitude}&lon=${longitude}&exclude=${part[4]}&appid=${WEATHER_API_KEY}&units=metric`
);
const json = await response.json();
setDays(json.daily);

 

# 2.10 Icons

 

expo를 설치했다면

`@expo/vector-icons` 패키지를 사용할 수 있습니다.

이 패키지를 이용하여 icon을 사용할 수 있습니다.

 

## Expo Vector Icons

 

공식문서

https://docs.expo.dev/guides/icons/

 

아이콘 종류

https://icons.expo.fyi/

 

코드 사용 예

import * as React from 'react';
import { View, StyleSheet } from 'react-native';
import Ionicons from '@expo/vector-icons/Ionicons';

export default function App() {
  return (
    <View style={styles.container}>
      <Ionicons name="md-checkmark-circle" size={32} color="green" />
    </View>
  );
}

const styles = StyleSheet.create({ ... });

 

## 참고

 

날씨 종류

https://openweathermap.org/weather-conditions

 

기존에 정의한 스타일을 그대로 사용하면서 추가로 다른 스타일을 추가하고 싶다면 

<View key={index} style={{...styles.day, alignItems: "center"}}>

 

# 날씨 앱 최종 코드

import { StatusBar } from "expo-status-bar";
import { useEffect, useState } from "react";
import {
  StyleSheet,
  Text,
  View,
  ScrollView,
  Dimensions,
  ActivityIndicator,
} from "react-native";
import * as Location from "expo-location";
import { GOOGLE_API_KEY, WEATHER_API_KEY } from "@env";
import { Ionicons } from "@expo/vector-icons";
import { Fontisto } from "@expo/vector-icons";

const { width: SCREEN_WIDTH } = Dimensions.get("window");

const icons = {
  Clouds: "cloudy",
  Clear: "day-sunny",
  Snow: "snowflake",
  Rain: "rain",
  Atmosphere: "cloudy-gusts",
  Drizzle: "day-rain",
  Thunderstorm: "lightning",
};

export default function App() {
  const [city, setCity] = useState("Loading...");
  const [days, setDays] = useState([]);
  const [ok, setOk] = useState(true);

  const getWeather = async () => {
    const { granted } = await Location.requestForegroundPermissionsAsync();
    if (!granted) {
      setOk(false);
    }
    const {
      coords: { latitude, longitude },
    } = await Location.getCurrentPositionAsync({ accuracy: 5 });
    Location.setGoogleApiKey(GOOGLE_API_KEY);
    const location = await Location.reverseGeocodeAsync(
      {
        latitude,
        longitude,
      },
      { useGoogleMaps: false }
    );
    setCity(location[0].city || location[0].region);
    // console.log(location);
    const part = ["current", "minutely", "hourly", "daily", "alerts"];
    const response = await fetch(
      `https://api.openweathermap.org/data/2.5/onecall?lat=${latitude}&lon=${longitude}&exclude=${part[4]}&appid=${WEATHER_API_KEY}&units=metric`
    );
    const json = await response.json();
    console.log("json : ", json);
    setDays(json.daily);
  };

  useEffect(() => {
    getWeather();
  }, []);

  return (
    <View style={styles.container}>
      <View style={styles.city}>
        <Text style={styles.cityName}>{city}</Text>
      </View>
      <View style={styles.weatherWrapper}>
        <ScrollView
          horizontal
          pagingEnabled
          indicatorStyle="white"
          // showsHorizontalScrollIndicator={false}
          contentContainerStyle={styles.weather}
        >
          {days.length === 0 ? (
            <View style={{ ...styles.day, alignItems: "center" }}>
              <ActivityIndicator
                color="white"
                style={{ marginTop: 10 }}
                size="large"
              />
            </View>
          ) : (
            days.map((day, index) => (
              <View key={index} style={styles.day}>
                <Text style={styles.date}>
                  {new Date(day.dt * 1000).toString().substring(0, 10)}
                </Text>
                <View
                  style={{
                    flexDirection: "row",
                    alignItems: "center",
                    width: "100%",
                    justifyContent: "space-between",
                  }}
                >
                  <Text style={styles.temp}>
                    {parseFloat(day.temp.day).toFixed(1)}
                  </Text>
                  <Fontisto
                    name={icons[day.weather[0].main]}
                    size={68}
                    color="white"
                  />
                </View>

                <Text style={styles.description}>{day.weather[0].main}</Text>
                <Text style={styles.tinyText}>
                  {day.weather[0].description}
                </Text>
              </View>
            ))
          )}
        </ScrollView>
      </View>

      <StatusBar style="dark" />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "blue",
  },
  city: {
    flex: 1.5,
    justifyContent: "center",
    alignItems: "center",
  },
  cityName: {
    fontSize: 58,
    fontWeight: "500",
    color: "white",
  },
  weatherWrapper: {
    flex: 3,
  },
  weather: {
    // backgroundColor: "blue",
    // flex: 3,
  },
  day: {
    width: SCREEN_WIDTH,
    // flex: 1,
    alignItems: "flex-start",
    paddingHorizontal: 20,
  },
  date: {
    marginTop: 50,
    fontSize: 35,
    color: "white",
  },
  temp: {
    fontWeight: "600",
    fontSize: 100,
    color: "white",
  },
  description: {
    marginTop: -10,
    fontSize: 30,
    color: "white",
    fontWeight: "500",
  },
  tinyText: {
    marginTop: -5,
    fontSize: 25,
    color: "white",
    fontWeight: "500",
  },
});