├── .github
├── ISSUE_TEMPLATE
│ └── issue_template.md
└── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── org
│ │ └── shortweather
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── org
│ │ │ └── shortweather
│ │ │ ├── ShortWeatherApplication.kt
│ │ │ ├── data
│ │ │ ├── api
│ │ │ │ ├── AuthService.kt
│ │ │ │ ├── CustomWeatherService.kt
│ │ │ │ └── TodayWeatherService.kt
│ │ │ ├── model
│ │ │ │ ├── BaseResponse.kt
│ │ │ │ ├── CustomWeather.kt
│ │ │ │ ├── SettingTimeData.kt
│ │ │ │ ├── TodayWeather.kt
│ │ │ │ ├── UserData.kt
│ │ │ │ └── WeeklyWeather.kt
│ │ │ ├── repository
│ │ │ │ ├── AuthRepositoryImpl.kt
│ │ │ │ ├── CustomWeatherRepositoryImpl.kt
│ │ │ │ └── TodayWeatherRepositoryImpl.kt
│ │ │ └── source
│ │ │ │ └── remote
│ │ │ │ ├── AuthRemoteDataSource.kt
│ │ │ │ ├── CustomWeatherRemoteDataSource.kt
│ │ │ │ └── TodayWeatherRemoteDataSource.kt
│ │ │ ├── di
│ │ │ ├── NetworkModule.kt
│ │ │ ├── RepositoryModule.kt
│ │ │ └── ServiceModule.kt
│ │ │ ├── domain
│ │ │ └── repository
│ │ │ │ ├── AuthRepository.kt
│ │ │ │ ├── CustomWeatherRepository.kt
│ │ │ │ └── TodayWeatherRepository.kt
│ │ │ ├── presentation
│ │ │ ├── MainActivity.kt
│ │ │ ├── MainViewModel.kt
│ │ │ ├── alarmsetting
│ │ │ │ ├── view
│ │ │ │ │ └── AlarmSettingActivity.kt
│ │ │ │ └── viewmodel
│ │ │ │ │ └── AlarmSettingViewModel.kt
│ │ │ ├── customweather
│ │ │ │ ├── adapter
│ │ │ │ │ ├── CustomWeatherPrecipitationAdapter.kt
│ │ │ │ │ └── CustomWeatherTempAdapter.kt
│ │ │ │ ├── view
│ │ │ │ │ └── CustomWeatherFragment.kt
│ │ │ │ └── viewmodel
│ │ │ │ │ └── CustomWeatherViewModel.kt
│ │ │ ├── input
│ │ │ │ ├── adapter
│ │ │ │ │ └── BottomSheetAdapter.kt
│ │ │ │ ├── view
│ │ │ │ │ ├── BottomSheetFragment.kt
│ │ │ │ │ ├── BottomSheetTimeFragment.kt
│ │ │ │ │ ├── InputInfoActivity.kt
│ │ │ │ │ └── InputTimeActivity.kt
│ │ │ │ └── viewmodel
│ │ │ │ │ ├── InputInfoViewModel.kt
│ │ │ │ │ └── InputTimeViewModel.kt
│ │ │ ├── othertimesetting
│ │ │ │ └── view
│ │ │ │ │ └── OtherTimeSettingActivity.kt
│ │ │ ├── setting
│ │ │ │ └── view
│ │ │ │ │ └── SettingFragment.kt
│ │ │ ├── splash
│ │ │ │ └── SplashActivity.kt
│ │ │ ├── todayweather
│ │ │ │ ├── adapter
│ │ │ │ │ └── TodayWeatherAdapter.kt
│ │ │ │ ├── view
│ │ │ │ │ └── TodayWeatherFragment.kt
│ │ │ │ └── viewmodel
│ │ │ │ │ └── TodayWeatherViewModel.kt
│ │ │ ├── todayweathercontainer
│ │ │ │ ├── OnPageDownClickListener.kt
│ │ │ │ ├── adapter
│ │ │ │ │ └── TodayWeatherContainerAdapter.kt
│ │ │ │ ├── view
│ │ │ │ │ └── TodayWeatherContainerFragment.kt
│ │ │ │ └── viewmodel
│ │ │ │ │ └── TodayWeatherContainerViewModel.kt
│ │ │ ├── waketimesetting
│ │ │ │ └── view
│ │ │ │ │ └── WakeTimeSettingActivity.kt
│ │ │ └── weeklyweather
│ │ │ │ ├── adapter
│ │ │ │ └── WeeklyWeatherAdapter.kt
│ │ │ │ ├── view
│ │ │ │ └── WeeklyWeatherFragment.kt
│ │ │ │ └── viewmodel
│ │ │ │ └── WeeklyWeatherViewModel.kt
│ │ │ └── util
│ │ │ ├── Constants.kt
│ │ │ ├── Event.kt
│ │ │ ├── EventObserver.kt
│ │ │ ├── ItemDiffCallback.kt
│ │ │ ├── NestedScrollableHost.kt
│ │ │ ├── OnThrottleClickListener.kt
│ │ │ ├── ShortWeatherFirebaseMessagingService.kt
│ │ │ ├── ShortWeatherSharedPreference.kt
│ │ │ ├── binding
│ │ │ ├── BindingActivity.kt
│ │ │ ├── BindingAdapter.kt
│ │ │ └── BindingFragment.kt
│ │ │ └── extension
│ │ │ ├── ActivityExt.kt
│ │ │ ├── ContextExt.kt
│ │ │ ├── LiveDataExt.kt
│ │ │ └── ViewExt.kt
│ └── res
│ │ ├── drawable-hdpi
│ │ ├── img_clear_day.png
│ │ ├── img_clear_night.png
│ │ ├── img_cloudy.png
│ │ ├── img_lightrain.png
│ │ ├── img_lightsnow.png
│ │ ├── img_lotcloud_day.png
│ │ ├── img_lotcloud_night.png
│ │ ├── img_rain.png
│ │ ├── img_rainsnow.png
│ │ ├── img_shower.png
│ │ ├── img_snow.png
│ │ └── img_snowdrifting.png
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable-xhdpi
│ │ ├── img_clear_day.png
│ │ ├── img_clear_night.png
│ │ ├── img_cloudy.png
│ │ ├── img_lightrain.png
│ │ ├── img_lightsnow.png
│ │ ├── img_lotcloud_day.png
│ │ ├── img_lotcloud_night.png
│ │ ├── img_rain.png
│ │ ├── img_rainsnow.png
│ │ ├── img_shower.png
│ │ ├── img_snow.png
│ │ └── img_snowdrifting.png
│ │ ├── drawable-xxhdpi
│ │ ├── img_clear_day.png
│ │ ├── img_clear_night.png
│ │ ├── img_cloudy.png
│ │ ├── img_lightrain.png
│ │ ├── img_lightsnow.png
│ │ ├── img_lotcloud_day.png
│ │ ├── img_lotcloud_night.png
│ │ ├── img_rain.png
│ │ ├── img_rainsnow.png
│ │ ├── img_shower.png
│ │ ├── img_snow.png
│ │ └── img_snowdrifting.png
│ │ ├── drawable-xxxhdpi
│ │ ├── img_clear_day.png
│ │ ├── img_clear_night.png
│ │ ├── img_cloudy.png
│ │ ├── img_lightrain.png
│ │ ├── img_lightsnow.png
│ │ ├── img_lotcloud_day.png
│ │ ├── img_lotcloud_night.png
│ │ ├── img_rain.png
│ │ ├── img_rainsnow.png
│ │ ├── img_shower.png
│ │ ├── img_snow.png
│ │ └── img_snowdrifting.png
│ │ ├── drawable
│ │ ├── bg_bad_dust.xml
│ │ ├── bg_blue_circle.xml
│ │ ├── bg_blue_newsflash.xml
│ │ ├── bg_bottom_sheet.xml
│ │ ├── bg_bottom_sheet_btn_blue.xml
│ │ ├── bg_bottom_sheet_btn_gray.xml
│ │ ├── bg_cloud.xml
│ │ ├── bg_day.xml
│ │ ├── bg_fog.xml
│ │ ├── bg_good_dust.xml
│ │ ├── bg_gray_circle.xml
│ │ ├── bg_night.xml
│ │ ├── bg_nomal_dust.xml
│ │ ├── bg_rain.xml
│ │ ├── bg_red_newsflash.xml
│ │ ├── bg_snow.xml
│ │ ├── bg_today_weather_description.xml
│ │ ├── bg_today_weather_sub_description.xml
│ │ ├── bg_today_weather_toast.xml
│ │ ├── bg_windy.xml
│ │ ├── bg_worst_dust.xml
│ │ ├── bg_yellow_newsflash.xml
│ │ ├── bg_yellowdust.xml
│ │ ├── btn_input_info.xml
│ │ ├── ic_add.xml
│ │ ├── ic_bottom_sheet_drag_view.xml
│ │ ├── ic_clear_day.xml
│ │ ├── ic_clear_night.xml
│ │ ├── ic_clothes.xml
│ │ ├── ic_cloudy.xml
│ │ ├── ic_dust_bad.xml
│ │ ├── ic_dust_good.xml
│ │ ├── ic_dust_normal.xml
│ │ ├── ic_dust_worst.xml
│ │ ├── ic_expand.xml
│ │ ├── ic_expand_down.xml
│ │ ├── ic_expand_red.xml
│ │ ├── ic_expand_right.xml
│ │ ├── ic_fog.xml
│ │ ├── ic_hail.xml
│ │ ├── ic_hamberger.xml
│ │ ├── ic_heavyrain.xml
│ │ ├── ic_heavysnow.xml
│ │ ├── ic_humidity.xml
│ │ ├── ic_launcher_background.xml
│ │ ├── ic_lightning.xml
│ │ ├── ic_lightrain.xml
│ │ ├── ic_lightsnow.xml
│ │ ├── ic_littlecloud_day.xml
│ │ ├── ic_littlecloud_night.xml
│ │ ├── ic_location.xml
│ │ ├── ic_logo.xml
│ │ ├── ic_lotcloud_day.xml
│ │ ├── ic_lotcloud_night.xml
│ │ ├── ic_next_btn.xml
│ │ ├── ic_precipitation_1.xml
│ │ ├── ic_precipitation_10.xml
│ │ ├── ic_precipitation_2.xml
│ │ ├── ic_precipitation_3.xml
│ │ ├── ic_precipitation_4.xml
│ │ ├── ic_precipitation_5.xml
│ │ ├── ic_precipitation_6.xml
│ │ ├── ic_precipitation_7.xml
│ │ ├── ic_precipitation_8.xml
│ │ ├── ic_precipitation_9.xml
│ │ ├── ic_rain.xml
│ │ ├── ic_rainsnow.xml
│ │ ├── ic_setting.xml
│ │ ├── ic_shower.xml
│ │ ├── ic_snow.xml
│ │ ├── ic_snowdrifting.xml
│ │ ├── ic_sunrise.xml
│ │ ├── ic_sunset.xml
│ │ ├── ic_toast.xml
│ │ ├── ic_today.xml
│ │ ├── ic_week.xml
│ │ ├── ic_weekly_weather_example.xml
│ │ ├── ic_windy.xml
│ │ ├── ic_yellowdust.xml
│ │ ├── img_clear_day.png
│ │ ├── img_clear_night.png
│ │ ├── img_cloudy.png
│ │ ├── img_lightrain.png
│ │ ├── img_lightsnow.png
│ │ ├── img_lotcloud_day.png
│ │ ├── img_lotcloud_night.png
│ │ ├── img_rain.png
│ │ ├── img_rainsnow.png
│ │ ├── img_shower.png
│ │ ├── img_snow.png
│ │ ├── img_snowdrifting.png
│ │ ├── selector_input_btn_bg.xml
│ │ └── selector_input_btn_text_color.xml
│ │ ├── font
│ │ ├── pretendard_black.otf
│ │ ├── pretendard_bold.otf
│ │ ├── pretendard_extrabold.otf
│ │ ├── pretendard_extralight.otf
│ │ ├── pretendard_light.otf
│ │ ├── pretendard_medium.otf
│ │ ├── pretendard_regular.otf
│ │ ├── pretendard_semibold.otf
│ │ └── pretendard_thin.otf
│ │ ├── layout
│ │ ├── activity_alarm_setting.xml
│ │ ├── activity_input_info.xml
│ │ ├── activity_input_time.xml
│ │ ├── activity_main.xml
│ │ ├── activity_other_time_setting.xml
│ │ ├── activity_splash.xml
│ │ ├── activity_wake_time_setting.xml
│ │ ├── bottom_sheet_content.xml
│ │ ├── bottom_sheet_time_content.xml
│ │ ├── fragment_custom_weather.xml
│ │ ├── fragment_setting.xml
│ │ ├── fragment_today_weather.xml
│ │ ├── fragment_today_weather_container.xml
│ │ ├── fragment_weekly_weather.xml
│ │ ├── item_bottom_sheet.xml
│ │ ├── item_custom_weather_precipitation.xml
│ │ ├── item_custom_weather_weather.xml
│ │ ├── item_drawer_header.xml
│ │ ├── item_today_weather_fine_dust.xml
│ │ ├── item_today_weather_newsflash.xml
│ │ ├── item_today_weather_ultrafine_dust.xml
│ │ └── item_weekly_weather.xml
│ │ ├── menu
│ │ ├── menu_drawer.xml
│ │ └── menu_tool_bar.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.webp
│ │ ├── ic_launcher_round.webp
│ │ └── ic_short_weather.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.webp
│ │ ├── ic_launcher_round.webp
│ │ └── ic_short_weather.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.webp
│ │ ├── ic_launcher_round.webp
│ │ └── ic_short_weather.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.webp
│ │ ├── ic_launcher_round.webp
│ │ └── ic_short_weather.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.webp
│ │ ├── ic_launcher_round.webp
│ │ └── ic_short_weather.png
│ │ ├── raw
│ │ └── shortweather_final.json
│ │ ├── values-night
│ │ └── themes.xml
│ │ ├── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ ├── styles.xml
│ │ └── themes.xml
│ │ └── xml
│ │ ├── backup_rules.xml
│ │ └── data_extraction_rules.xml
│ └── test
│ └── java
│ └── org
│ └── shortweather
│ └── ExampleUnitTest.kt
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.github/ISSUE_TEMPLATE/issue_template.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: ISSUE_TEMPLATE
3 | about: "숏웨더 기본 이슈 템플릿입니다."
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | ## Issue 📌
11 |
12 | ## Todo 📝
13 | - [ ]
14 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## Issue 📌
2 |
3 | ## Description ✏
4 | -
5 |
6 | ## **ScreenShot ✨**
7 |
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 🌩 숏웨더 🌩
2 | ### 어제의 날씨로 알아보는 오늘의 날씨
3 |
4 |
5 |
6 | ## Contributors 🌥
7 | | [@SunwoongH](https://github.com/SunwoongH) | [@chaso1495](https://github.com/chaso1495) | [@ahra1221](https://github.com/ahra1221) |
8 | | :---: | :---: | :---: |
9 | |
|
|
|
10 | |**오늘 날씨 & 맞춤 날씨 뷰**|**정보 입력 & 스플래쉬 & 설정 뷰**|**주간 날씨 & 설정 뷰**|
11 |
12 |
13 |
14 | 
15 |
16 | ## Android Coding Convention 🌦
17 | [android coding convention 📝](https://devjoy.notion.site/Android-Coding-Convention-2d1428b408614047a1fafa698383d4e0)
18 |
19 |
20 |
21 | ## Git Convention 🌨
22 | [git convention 📝](https://devjoy.notion.site/Git-Convention-bab184da78c548f085b02026bbb86cbe)
23 |
24 |
25 |
26 | ## Teck Stack ⛈
27 |
28 | | Architecture | Clean Architecture, MVVM |
29 | |:---|:---|
30 | | Design Pattern | Repository Pattern, Adapter Pattern, Delegation Pattern, Observer Pattern |
31 | | Jetpack Components | LiveData, Lifecycle, ViewModel, DataBinding |
32 | | Dependency Injection | Hilt |
33 | | Network | Retrofit, OkHttp |
34 | | Asynchronous Processing | Coroutine |
35 | | Third Party Library | Lottie, kotlinSerialization, Firebase |
36 | | Strategy | Git Flow |
37 | | Other Tool | Slack, Notion, Figma, Postman |
38 |
39 |
40 |
41 | ## 시연 영상 ⛅
42 |
43 |
44 |
45 |
46 | ## Foldering 🌩
47 | ```
48 | 📂 org.shortweather
49 | ┣ 📂 data
50 | ┃ ┣ 📂 api
51 | ┃ ┣ 📂 model
52 | ┃ ┣ 📂 repository
53 | ┃ ┣ 📂 source
54 | ┃ ┣ 📂 local
55 | ┃ ┣ 📂 remote
56 | ┣ 📂 di
57 | ┣ 📂 domain
58 | ┃ ┣ 📂 repository
59 | ┣ 📂 presentation
60 | ┃ ┣ 📂 alarmsetting
61 | ┃ ┣ 📂 customweather
62 | ┃ ┣ 📂 input
63 | ┃ ┣ 📂 othertimesetting
64 | ┃ ┣ 📂 setting
65 | ┃ ┣ 📂 splash
66 | ┃ ┣ 📂 todayweather
67 | ┃ ┣ 📂 todayweathercontainer
68 | ┃ ┣ 📂 adapter
69 | ┃ ┣ 📂 view
70 | ┃ ┣ 📂 viewmodel
71 | ┃ ┣ 📂 waketimesetting
72 | ┃ ┣ 📂 weeklyweather
73 | ┣ 📂 util
74 | ┃ ┣ 📂 binding
75 | ┃ ┣ 📂 extension
76 | ```
77 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/app/src/androidTest/java/org/shortweather/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("org.shortweather", appContext.packageName)
23 | }
24 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
19 |
23 |
27 |
31 |
35 |
39 |
43 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/ShortWeatherApplication.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather
2 |
3 | import android.app.Application
4 | import android.content.SharedPreferences
5 | import com.google.firebase.messaging.FirebaseMessaging
6 | import dagger.hilt.android.HiltAndroidApp
7 | import org.shortweather.util.ShortWeatherSharedPreference
8 |
9 |
10 | @HiltAndroidApp
11 | class ShortWeatherApplication : Application(){
12 | override fun onCreate() {
13 | super.onCreate()
14 | ShortWeatherSharedPreference.setDeviceToken(this)
15 | }
16 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/data/api/AuthService.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.data.api
2 |
3 | import org.shortweather.data.model.BaseResponse
4 | import org.shortweather.data.model.RequestUserInfo
5 | import org.shortweather.data.model.ResponseUserCheck
6 | import org.shortweather.data.model.ResponseUserInfo
7 | import retrofit2.http.*
8 |
9 | interface AuthService {
10 | /**
11 | * 유저 정보 입력 API
12 | */
13 | @POST("auth")
14 | suspend fun createUser(
15 | @Body requestUserInfo: RequestUserInfo
16 | ): BaseResponse
17 |
18 | /**
19 | * 유저 등록 조회 API
20 | */
21 | @GET("auth/login")
22 | suspend fun searchUser(
23 | @Header("deviceToken") deviceToken: String
24 | ): BaseResponse
25 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/data/api/CustomWeatherService.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.data.api
2 |
3 | import org.shortweather.data.model.BaseResponse
4 | import org.shortweather.data.model.ResponseCustomWeatherDetail
5 | import org.shortweather.data.model.ResponseCustomWeatherRain
6 | import org.shortweather.data.model.ResponseCustomWeatherTemp
7 | import retrofit2.http.GET
8 | import retrofit2.http.Header
9 |
10 | interface CustomWeatherService {
11 | /**
12 | * 오늘 날씨 정보 조회 API
13 | */
14 | @GET("/weather/today/detail")
15 | suspend fun getDetail(
16 | @Header("Authorization") accessToken: String
17 | ): BaseResponse
18 |
19 | /**
20 | * 시간대별 날씨 화면 날씨 조회 API
21 | */
22 | @GET("weather/today/detail/temp")
23 | suspend fun getTemp(): BaseResponse>
24 |
25 | /**
26 | * 시간대별 날씨 화면 강수 조회 API
27 | */
28 | @GET("weather/today/detail/rain")
29 | suspend fun getRain(): BaseResponse>
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/data/api/TodayWeatherService.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.data.api
2 |
3 | import org.shortweather.data.model.BaseResponse
4 | import org.shortweather.data.model.ResponseTodayWeatherInfo
5 | import org.shortweather.data.model.ResponseTodayWeatherToastInfo
6 | import retrofit2.http.GET
7 | import retrofit2.http.Header
8 |
9 | interface TodayWeatherService {
10 | /**
11 | * 오늘 날씨 조회 API
12 | */
13 | @GET("weather/today")
14 | suspend fun getTodayWeatherInfo(
15 | @Header("Authorization") accessToken: String
16 | ): BaseResponse
17 |
18 | /**
19 | * 오늘 날씨 toast 조회 API
20 | */
21 | @GET("weather/today/question")
22 | suspend fun getTodayWeatherToastInfo(
23 | @Header("Authorization") accessToken: String
24 | ): BaseResponse
25 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/data/model/BaseResponse.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.data.model
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | data class BaseResponse(
7 | val status: Int,
8 | val success: Boolean,
9 | val message: String,
10 | val data: T? = null
11 | )
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/data/model/CustomWeather.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.data.model
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | data class ResponseCustomWeatherDetail(
7 | val location: String,
8 | val goOut: ResponseGoOut,
9 | val goHome: ResponseGoHome,
10 | val todayWeather: ResponseTodayWeather
11 | ) {
12 | @Serializable
13 | data class ResponseGoOut(
14 | val time: String,
15 | val temp : Int,
16 | val day: Boolean,
17 | val image: String
18 | )
19 |
20 | @Serializable
21 | data class ResponseGoHome(
22 | val time: String,
23 | val temp: Int,
24 | val day: Boolean,
25 | val image: String
26 | )
27 |
28 | @Serializable
29 | data class ResponseTodayWeather(
30 | val humidity: Int,
31 | val sunrise: String,
32 | val sunset: String,
33 | val fineDust: Int,
34 | val ultraFineDust: Int
35 | )
36 | }
37 |
38 | @Serializable
39 | data class ResponseCustomWeatherTemp(
40 | val date: String,
41 | val time: String,
42 | val temperature: Int,
43 | val day: Boolean,
44 | val image: String
45 | )
46 |
47 | data class CustomWeatherTemp(
48 | val data: ResponseCustomWeatherTemp,
49 | val isCurrent: Boolean = false
50 | )
51 |
52 | @Serializable
53 | data class ResponseCustomWeatherRain(
54 | val date: String,
55 | val time: String,
56 | val rain: Int
57 | )
58 |
59 | data class CustomWeatherPrecipitation(
60 | val data: ResponseCustomWeatherRain,
61 | val isCurrent: Boolean = false
62 | )
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/data/model/SettingTimeData.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.data.model
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | data class RequestOtherTime(
7 | val goOutTime: String,
8 | val goHomeTime: String
9 | )
10 |
11 | @Serializable
12 | data class ResponseOtherTime(
13 | val id: Int,
14 | val goOutTime: String,
15 | val goHomeTime: String
16 | )
17 |
18 | @Serializable
19 | data class RequestWakeTime(
20 | val wakeUpTime: String
21 | )
22 |
23 | @Serializable
24 | data class ResponseWakeTime(
25 | val id: Int,
26 | val wakeUpTime: String
27 | )
28 |
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/data/model/TodayWeather.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.data.model
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | sealed class TodayWeatherTag
6 |
7 | data class Newsflash(
8 | val description: String
9 | ) : TodayWeatherTag()
10 |
11 | data class FineDust(
12 | val fineDustLevel: Int
13 | ) : TodayWeatherTag()
14 |
15 | data class UltrafineDust(
16 | val ultrafineDustLevel: Int
17 | ) : TodayWeatherTag()
18 |
19 | @Serializable
20 | data class ResponseTodayWeatherInfo(
21 | val location: String,
22 | val compareTemp: Int,
23 | val compareMessage: String,
24 | val breakingNews: String?,
25 | val fineDust: Int,
26 | val ultrafineDust: Int,
27 | val day: Boolean,
28 | val image: String,
29 | val currentTemp: Int,
30 | val minTemp: Int,
31 | val maxTemp: Int,
32 | val weatherMessage: String
33 | )
34 |
35 | @Serializable
36 | data class ResponseTodayWeatherToastInfo(
37 | val temp: Int,
38 | val weatherMessage: String
39 | )
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/data/model/UserData.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.data.model
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | // 유저 등록 조회 Request -> Header로 바로 처리
6 |
7 | // 유저 등록 조회 Response
8 | @Serializable
9 | data class ResponseUserCheck(
10 | val deviceToken: String,
11 | val accessToken: String?,
12 | val isExist: Boolean
13 | )
14 |
15 | // 유저 정보 입력 Request
16 | @Serializable
17 | data class RequestUserInfo(
18 | val gender: String,
19 | val age: String,
20 | val tempSens: String,
21 | val wakeUpTime: String,
22 | val goOutTime: String,
23 | val goHomeTime: String,
24 | val deviceToken: String,
25 | )
26 |
27 | // 유저 정보 입력 Response
28 | @Serializable
29 | data class ResponseUserInfo(
30 | val id: Int,
31 | val gender: String,
32 | val age: String,
33 | val tempSens: String,
34 | val wakeUpTime: String,
35 | val goOutTime: String,
36 | val goHomeTime: String,
37 | val deviceToken: String,
38 | val accessToken: String
39 | )
40 |
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/data/model/WeeklyWeather.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.data.model
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | data class WeeklyWeather(
7 | val day: String,
8 | val date: String,
9 | val dayImage: String,
10 | val dayRain: Int,
11 | val nightImage: String,
12 | val nightRain: Int,
13 | val isDay: Boolean,
14 | val minTemp: Int,
15 | val maxTemp: Int
16 | )
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/data/repository/AuthRepositoryImpl.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.data.repository
2 |
3 | import org.shortweather.data.model.BaseResponse
4 | import org.shortweather.data.model.RequestUserInfo
5 | import org.shortweather.data.model.ResponseUserCheck
6 | import org.shortweather.data.model.ResponseUserInfo
7 | import org.shortweather.data.source.remote.AuthRemoteDataSource
8 | import org.shortweather.domain.repository.AuthRepository
9 | import javax.inject.Inject
10 |
11 | class AuthRepositoryImpl @Inject constructor(private val authRemoteDataSource: AuthRemoteDataSource) :
12 | AuthRepository {
13 | override suspend fun searchUser(deviceToken: String): BaseResponse =
14 | authRemoteDataSource.searchUser(deviceToken)
15 |
16 | override suspend fun createUser(requestUserInfo: RequestUserInfo): BaseResponse =
17 | authRemoteDataSource.createUser(requestUserInfo)
18 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/data/repository/CustomWeatherRepositoryImpl.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.data.repository
2 |
3 | import org.shortweather.data.model.BaseResponse
4 | import org.shortweather.data.model.ResponseCustomWeatherDetail
5 | import org.shortweather.data.model.ResponseCustomWeatherRain
6 | import org.shortweather.data.model.ResponseCustomWeatherTemp
7 | import org.shortweather.data.source.remote.CustomWeatherRemoteDataSource
8 | import org.shortweather.domain.repository.CustomWeatherRepository
9 | import javax.inject.Inject
10 |
11 | class CustomWeatherRepositoryImpl @Inject constructor(
12 | private val customWeatherDataSource: CustomWeatherRemoteDataSource
13 | ) : CustomWeatherRepository {
14 | override suspend fun getDetail(accessToken: String): BaseResponse =
15 | customWeatherDataSource.getDetail(accessToken)
16 |
17 | override suspend fun getTemp(): BaseResponse> =
18 | customWeatherDataSource.getTemp()
19 |
20 | override suspend fun getRain(): BaseResponse> =
21 | customWeatherDataSource.getRain()
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/data/repository/TodayWeatherRepositoryImpl.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.data.repository
2 |
3 | import org.shortweather.data.model.BaseResponse
4 | import org.shortweather.data.model.ResponseTodayWeatherInfo
5 | import org.shortweather.data.model.ResponseTodayWeatherToastInfo
6 | import org.shortweather.data.source.remote.TodayWeatherRemoteDataSource
7 | import org.shortweather.domain.repository.TodayWeatherRepository
8 | import javax.inject.Inject
9 |
10 | class TodayWeatherRepositoryImpl @Inject constructor(
11 | private val todayWeatherRemoteDataSource: TodayWeatherRemoteDataSource
12 | ) : TodayWeatherRepository {
13 | override suspend fun getTodayWeatherInfo(accessToken: String): BaseResponse =
14 | todayWeatherRemoteDataSource.getTodayWeatherInfo(accessToken)
15 |
16 | override suspend fun getTodayWeatherToastInfo(accessToken: String): BaseResponse =
17 | todayWeatherRemoteDataSource.getTodayWeatherToastInfo(accessToken)
18 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/data/source/remote/AuthRemoteDataSource.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.data.source.remote
2 |
3 | import org.shortweather.data.api.AuthService
4 | import org.shortweather.data.model.BaseResponse
5 | import org.shortweather.data.model.RequestUserInfo
6 | import org.shortweather.data.model.ResponseUserCheck
7 | import org.shortweather.data.model.ResponseUserInfo
8 | import javax.inject.Inject
9 |
10 | class AuthRemoteDataSource @Inject constructor(
11 | private val authservice: AuthService
12 | ) {
13 | suspend fun createUser(requestUserInfo: RequestUserInfo): BaseResponse =
14 | authservice.createUser(requestUserInfo)
15 |
16 | suspend fun searchUser(deviceToken: String): BaseResponse =
17 | authservice.searchUser(deviceToken)
18 | }
19 |
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/data/source/remote/CustomWeatherRemoteDataSource.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.data.source.remote
2 |
3 | import org.shortweather.data.api.CustomWeatherService
4 | import org.shortweather.data.model.BaseResponse
5 | import org.shortweather.data.model.ResponseCustomWeatherDetail
6 | import org.shortweather.data.model.ResponseCustomWeatherRain
7 | import org.shortweather.data.model.ResponseCustomWeatherTemp
8 | import javax.inject.Inject
9 |
10 | class CustomWeatherRemoteDataSource @Inject constructor(
11 | private val customWeatherService: CustomWeatherService
12 | ) {
13 | suspend fun getDetail(accessToken: String):
14 | BaseResponse = customWeatherService.getDetail(accessToken)
15 |
16 | suspend fun getTemp():
17 | BaseResponse> = customWeatherService.getTemp()
18 |
19 | suspend fun getRain():
20 | BaseResponse> = customWeatherService.getRain()
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/data/source/remote/TodayWeatherRemoteDataSource.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.data.source.remote
2 |
3 | import org.shortweather.data.api.TodayWeatherService
4 | import org.shortweather.data.model.BaseResponse
5 | import org.shortweather.data.model.ResponseTodayWeatherInfo
6 | import org.shortweather.data.model.ResponseTodayWeatherToastInfo
7 | import javax.inject.Inject
8 |
9 | class TodayWeatherRemoteDataSource @Inject constructor(
10 | private val todayWeatherService: TodayWeatherService
11 | ) {
12 | suspend fun getTodayWeatherInfo(accessToken: String): BaseResponse =
13 | todayWeatherService.getTodayWeatherInfo(accessToken)
14 |
15 | suspend fun getTodayWeatherToastInfo(accessToken: String): BaseResponse =
16 | todayWeatherService.getTodayWeatherToastInfo(accessToken)
17 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/di/NetworkModule.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.di
2 |
3 | import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
4 | import dagger.Module
5 | import dagger.Provides
6 | import dagger.hilt.InstallIn
7 | import dagger.hilt.components.SingletonComponent
8 | import kotlinx.serialization.ExperimentalSerializationApi
9 | import kotlinx.serialization.json.Json
10 | import okhttp3.MediaType.Companion.toMediaType
11 | import okhttp3.OkHttpClient
12 | import okhttp3.logging.HttpLoggingInterceptor
13 | import org.shortweather.BuildConfig.BASE_URL
14 | import retrofit2.Retrofit
15 | import java.util.concurrent.TimeUnit
16 | import javax.inject.Qualifier
17 | import javax.inject.Singleton
18 |
19 | @Module
20 | @InstallIn(SingletonComponent::class)
21 | object NetworkModule {
22 | @Provides
23 | @Singleton
24 | fun providesHttpLoggingInterceptor(): HttpLoggingInterceptor = HttpLoggingInterceptor().apply {
25 | level = HttpLoggingInterceptor.Level.BODY
26 | }
27 |
28 | @Provides
29 | @Singleton
30 | fun providesOkHttpClient(httpLoggingInterceptor: HttpLoggingInterceptor): OkHttpClient =
31 | OkHttpClient.Builder()
32 | .connectTimeout(10, TimeUnit.SECONDS)
33 | .writeTimeout(10, TimeUnit.SECONDS)
34 | .readTimeout(10, TimeUnit.SECONDS)
35 | .addInterceptor(httpLoggingInterceptor)
36 | .build()
37 |
38 | @Provides
39 | @Singleton
40 | @ExperimentalSerializationApi
41 | fun providesRetrofit(okHttpClient: OkHttpClient): Retrofit = Retrofit.Builder()
42 | .baseUrl(BASE_URL)
43 | .client(okHttpClient)
44 | .addConverterFactory(Json.asConverterFactory("application/json".toMediaType()))
45 | .build()
46 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/di/RepositoryModule.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.di
2 |
3 | import dagger.Binds
4 | import dagger.Module
5 | import dagger.hilt.InstallIn
6 | import dagger.hilt.components.SingletonComponent
7 | import org.shortweather.data.repository.AuthRepositoryImpl
8 | import org.shortweather.data.repository.CustomWeatherRepositoryImpl
9 | import org.shortweather.data.repository.TodayWeatherRepositoryImpl
10 | import org.shortweather.domain.repository.AuthRepository
11 | import org.shortweather.domain.repository.CustomWeatherRepository
12 | import org.shortweather.domain.repository.TodayWeatherRepository
13 | import javax.inject.Singleton
14 |
15 | @Module
16 | @InstallIn(SingletonComponent::class)
17 | abstract class RepositoryModule {
18 | @Binds
19 | @Singleton
20 | abstract fun bindsAuthRepository(authRepositoryImpl: AuthRepositoryImpl): AuthRepository
21 |
22 | @Binds
23 | @Singleton
24 | abstract fun bindsTodayWeatherRepository(todayWeatherRepositoryImpl: TodayWeatherRepositoryImpl): TodayWeatherRepository
25 |
26 | @Binds
27 | @Singleton
28 | abstract fun bindsWeatherRepository(customWeatherRepository: CustomWeatherRepositoryImpl): CustomWeatherRepository
29 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/di/ServiceModule.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.di
2 |
3 | import dagger.Module
4 | import dagger.Provides
5 | import dagger.hilt.InstallIn
6 | import dagger.hilt.components.SingletonComponent
7 | import org.shortweather.data.api.AuthService
8 | import org.shortweather.data.api.CustomWeatherService
9 | import org.shortweather.data.api.TodayWeatherService
10 | import retrofit2.Retrofit
11 | import javax.inject.Singleton
12 |
13 | @Module
14 | @InstallIn(SingletonComponent::class)
15 | object ServiceModule {
16 | @Provides
17 | @Singleton
18 | fun providesAuthService(retrofit: Retrofit): AuthService =
19 | retrofit.create(AuthService::class.java)
20 |
21 | @Provides
22 | @Singleton
23 | fun providesTodayWeatherService(retrofit: Retrofit): TodayWeatherService =
24 | retrofit.create(TodayWeatherService::class.java)
25 |
26 | @Provides
27 | @Singleton
28 | fun providesCustomWeatherService(retrofit: Retrofit): CustomWeatherService =
29 | retrofit.create(CustomWeatherService::class.java)
30 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/domain/repository/AuthRepository.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.domain.repository
2 |
3 | import org.shortweather.data.model.BaseResponse
4 | import org.shortweather.data.model.RequestUserInfo
5 | import org.shortweather.data.model.ResponseUserCheck
6 | import org.shortweather.data.model.ResponseUserInfo
7 |
8 | interface AuthRepository {
9 | suspend fun createUser(requestUserInfo: RequestUserInfo): BaseResponse
10 | suspend fun searchUser(deviceToken: String): BaseResponse
11 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/domain/repository/CustomWeatherRepository.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.domain.repository
2 |
3 | import org.shortweather.data.model.BaseResponse
4 | import org.shortweather.data.model.ResponseCustomWeatherDetail
5 | import org.shortweather.data.model.ResponseCustomWeatherRain
6 | import org.shortweather.data.model.ResponseCustomWeatherTemp
7 |
8 | interface CustomWeatherRepository {
9 | suspend fun getDetail(accessToken: String): BaseResponse
10 | suspend fun getTemp(): BaseResponse>
11 | suspend fun getRain(): BaseResponse>
12 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/domain/repository/TodayWeatherRepository.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.domain.repository
2 |
3 | import org.shortweather.data.model.BaseResponse
4 | import org.shortweather.data.model.ResponseTodayWeatherInfo
5 | import org.shortweather.data.model.ResponseTodayWeatherToastInfo
6 |
7 | interface TodayWeatherRepository {
8 | suspend fun getTodayWeatherInfo(accessToken: String): BaseResponse
9 | suspend fun getTodayWeatherToastInfo(accessToken: String): BaseResponse
10 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/presentation/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.presentation
2 |
3 | import android.os.Bundle
4 | import androidx.activity.viewModels
5 | import androidx.fragment.app.Fragment
6 | import dagger.hilt.android.AndroidEntryPoint
7 | import org.shortweather.R
8 | import org.shortweather.databinding.ActivityMainBinding
9 | import org.shortweather.presentation.setting.view.SettingFragment
10 | import org.shortweather.presentation.todayweathercontainer.view.TodayWeatherContainerFragment
11 | import org.shortweather.presentation.weeklyweather.view.WeeklyWeatherFragment
12 | import org.shortweather.util.binding.BindingActivity
13 | import org.shortweather.util.extension.replace
14 |
15 | @AndroidEntryPoint
16 | class MainActivity : BindingActivity(R.layout.activity_main) {
17 | private val viewModel: MainViewModel by viewModels()
18 | override fun onCreate(savedInstanceState: Bundle?) {
19 | super.onCreate(savedInstanceState)
20 |
21 | binding.viewModel = viewModel
22 | binding.lifecycleOwner = this
23 | initView()
24 | setNavigationItemSelectedListener()
25 | setNavigation()
26 | startTargetFragment(R.id.today_weather_menu_drawer)
27 | }
28 |
29 | private fun setTitle(text: String) {
30 | viewModel.setTitle(text)
31 | }
32 |
33 | private fun setIsSetting(setting: Boolean) {
34 | viewModel.setIsSetting(setting)
35 | }
36 |
37 | private fun initView() {
38 | binding.nvMain.itemIconTintList = null
39 | startTargetFragment(TodayWeatherContainerFragment())
40 | }
41 |
42 | private fun setNavigationItemSelectedListener() {
43 | binding.nvMain.setNavigationItemSelectedListener { menuItem ->
44 | startTargetFragment(menuItem.itemId)
45 | binding.dlMain.close()
46 | true
47 | }
48 | }
49 |
50 | private fun setNavigation() {
51 | binding.tbMain.setNavigationOnClickListener {
52 | binding.dlMain.open()
53 | }
54 | }
55 |
56 | private fun startTargetFragment(fragment: Fragment) {
57 | supportFragmentManager.beginTransaction()
58 | .replace(R.id.fcv_main, fragment)
59 | .commitAllowingStateLoss()
60 | }
61 |
62 | private fun startTargetFragment(itemId: Int) = when (itemId) {
63 | R.id.today_weather_menu_drawer -> {
64 | replace(R.id.fcv_main)
65 | setTitle(getString(R.string.title_today_weather))
66 | setIsSetting(true)
67 | }
68 | R.id.weekly_weather_menu_drawer -> {
69 | replace(R.id.fcv_main)
70 | setTitle(getString(R.string.title_weekly_weather))
71 | setIsSetting(true)
72 | }
73 | R.id.clothes_menu_drawer -> {}
74 | R.id.setting_menu_drawer -> {
75 | replace(R.id.fcv_main)
76 | setTitle(getString(R.string.title_setting))
77 | setIsSetting(false)
78 | }
79 | else -> throw IllegalArgumentException("Not found error.")
80 | }
81 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/presentation/MainViewModel.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.presentation
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.lifecycle.MutableLiveData
5 | import androidx.lifecycle.ViewModel
6 | import dagger.hilt.android.lifecycle.HiltViewModel
7 | import javax.inject.Inject
8 |
9 | @HiltViewModel
10 | class MainViewModel @Inject constructor() : ViewModel() {
11 | private val _title = MutableLiveData()
12 | val title: LiveData
13 | get() = _title
14 |
15 | private val _isSetting = MutableLiveData(false)
16 | val isSetting: LiveData
17 | get() = _isSetting
18 |
19 | fun setTitle(text: String) {
20 | _title.value = text
21 | }
22 |
23 | fun setIsSetting(setting: Boolean) {
24 | _isSetting.value = setting
25 | }
26 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/presentation/alarmsetting/view/AlarmSettingActivity.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.presentation.alarmsetting.view
2 |
3 | import android.os.Bundle
4 | import androidx.activity.viewModels
5 | import dagger.hilt.EntryPoint
6 | import dagger.hilt.android.AndroidEntryPoint
7 | import org.shortweather.R
8 | import org.shortweather.databinding.ActivityAlarmSettingBinding
9 | import org.shortweather.presentation.alarmsetting.viewmodel.AlarmSettingViewModel
10 | import org.shortweather.util.binding.BindingActivity
11 |
12 | @AndroidEntryPoint
13 | class AlarmSettingActivity :
14 | BindingActivity(R.layout.activity_alarm_setting) {
15 | private val viewModel by viewModels()
16 |
17 | override fun onCreate(savedInstanceState: Bundle?) {
18 | super.onCreate(savedInstanceState)
19 |
20 | binding.viewModel = viewModel
21 | binding.lifecycleOwner = this
22 | initView()
23 | setOnCheckedChangeListener()
24 | }
25 |
26 | private fun initView(){
27 | binding.btnAlarmSettingAll.isChecked = true
28 | binding.btnAlarmSettingWake.isChecked = true
29 | }
30 |
31 | private fun setOnCheckedChangeListener() {
32 | binding.btnAlarmSettingAll.setOnCheckedChangeListener { _, isChecked ->
33 | if (isChecked) {
34 | viewModel.setIsChange(true)
35 | } else {
36 | viewModel.setIsChange(false)
37 | }
38 | }
39 | }
40 | }
41 |
42 |
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/presentation/alarmsetting/viewmodel/AlarmSettingViewModel.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.presentation.alarmsetting.viewmodel
2 |
3 | import androidx.lifecycle.MutableLiveData
4 | import androidx.lifecycle.ViewModel
5 | import dagger.hilt.android.HiltAndroidApp
6 | import dagger.hilt.android.lifecycle.HiltViewModel
7 | import javax.inject.Inject
8 |
9 | @HiltViewModel
10 | class AlarmSettingViewModel @Inject constructor(): ViewModel() {
11 | val isChange = MutableLiveData(true)
12 |
13 | fun setIsChange(select: Boolean) {
14 | isChange.value = select
15 | }
16 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/presentation/customweather/adapter/CustomWeatherPrecipitationAdapter.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.presentation.customweather.adapter
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 | import androidx.recyclerview.widget.ListAdapter
6 | import androidx.recyclerview.widget.RecyclerView
7 | import org.shortweather.data.model.CustomWeatherPrecipitation
8 | import org.shortweather.databinding.ItemCustomWeatherPrecipitationBinding
9 | import org.shortweather.util.ItemDiffCallback
10 |
11 | class CustomWeatherPrecipitationAdapter :
12 | ListAdapter(
13 | ItemDiffCallback(
14 | onContentsTheSame = { oldItem, newItem -> oldItem == newItem },
15 | onItemsTheSame = { oldItem, newItem -> oldItem == newItem })
16 | ) {
17 | private lateinit var inflater: LayoutInflater
18 |
19 | override fun onCreateViewHolder(
20 | parent: ViewGroup,
21 | viewType: Int
22 | ): CustomWeatherPrecipitationViewHolder {
23 | if (!::inflater.isInitialized) {
24 | inflater = LayoutInflater.from(parent.context)
25 | }
26 | return CustomWeatherPrecipitationViewHolder(
27 | ItemCustomWeatherPrecipitationBinding.inflate(
28 | inflater,
29 | parent,
30 | false
31 | )
32 | )
33 | }
34 |
35 | override fun onBindViewHolder(holder: CustomWeatherPrecipitationViewHolder, position: Int) {
36 | holder.onBind(currentList[position])
37 | }
38 |
39 | class CustomWeatherPrecipitationViewHolder(
40 | private val binding: ItemCustomWeatherPrecipitationBinding
41 | ) : RecyclerView.ViewHolder(binding.root) {
42 | fun onBind(customWeatherPrecipitation: CustomWeatherPrecipitation) {
43 | binding.customWeatherPrecipitation = customWeatherPrecipitation
44 | binding.executePendingBindings()
45 | }
46 | }
47 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/presentation/customweather/adapter/CustomWeatherTempAdapter.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.presentation.customweather.adapter
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 | import androidx.recyclerview.widget.ListAdapter
6 | import androidx.recyclerview.widget.RecyclerView
7 | import org.shortweather.data.model.CustomWeatherTemp
8 | import org.shortweather.databinding.ItemCustomWeatherWeatherBinding
9 | import org.shortweather.util.ItemDiffCallback
10 |
11 | class CustomWeatherTempAdapter :
12 | ListAdapter(
13 | ItemDiffCallback(
14 | onContentsTheSame = { oldItem, newItem -> oldItem == newItem },
15 | onItemsTheSame = { oldItem, newItem -> oldItem == newItem })
16 | ) {
17 | private lateinit var inflater: LayoutInflater
18 |
19 | override fun onCreateViewHolder(
20 | parent: ViewGroup,
21 | viewType: Int
22 | ): CustomWeatherTempViewHolder {
23 | if (!::inflater.isInitialized) {
24 | inflater = LayoutInflater.from(parent.context)
25 | }
26 | return CustomWeatherTempViewHolder(
27 | ItemCustomWeatherWeatherBinding.inflate(
28 | inflater,
29 | parent,
30 | false
31 | )
32 | )
33 | }
34 |
35 | override fun onBindViewHolder(holder: CustomWeatherTempViewHolder, position: Int) {
36 | holder.onBind(currentList[position])
37 | }
38 |
39 | class CustomWeatherTempViewHolder(
40 | private val binding: ItemCustomWeatherWeatherBinding
41 | ) : RecyclerView.ViewHolder(binding.root) {
42 | fun onBind(responseTemp: CustomWeatherTemp) {
43 | binding.customWeatherTemp = responseTemp
44 | binding.executePendingBindings()
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/presentation/input/adapter/BottomSheetAdapter.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.presentation.input.adapter
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 | import androidx.core.app.NotificationCompat.getColor
6 | import androidx.recyclerview.widget.RecyclerView
7 | import org.shortweather.R
8 | import org.shortweather.databinding.ItemBottomSheetBinding
9 |
10 | class BottomSheetAdapter(
11 | private val list: MutableList,
12 | private val listener: OnItemClickListener
13 | ) : RecyclerView.Adapter() {
14 | private var itemList: MutableList = list
15 | private lateinit var inflater: LayoutInflater
16 |
17 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): InfoItemHolder {
18 | if (!::inflater.isInitialized) {
19 | inflater = LayoutInflater.from(parent.context)
20 | }
21 | return InfoItemHolder(ItemBottomSheetBinding.inflate(inflater, parent, false))
22 | }
23 |
24 | override fun onBindViewHolder(holder: InfoItemHolder, position: Int) {
25 | val item = itemList[position]
26 | holder.onBind(item)
27 | }
28 |
29 | override fun getItemCount(): Int = itemList.size
30 |
31 | inner class InfoItemHolder(
32 | private val binding: ItemBottomSheetBinding
33 | ) : RecyclerView.ViewHolder(binding.root) {
34 | fun onBind(item: BottomSheetItem) {
35 | binding.root.setOnClickListener {
36 | listener.onItemClick(item)
37 | }
38 | binding.tvContents.text = item.contents
39 | }
40 | }
41 |
42 | interface OnItemClickListener {
43 | fun onItemClick(item: BottomSheetItem)
44 | }
45 | }
46 |
47 | data class BottomSheetItem(var contents: String) // 선택할 아이템
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/presentation/input/viewmodel/InputInfoViewModel.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.presentation.input.viewmodel
2 |
3 | import androidx.lifecycle.*
4 | import dagger.hilt.android.lifecycle.HiltViewModel
5 | import javax.inject.Inject
6 |
7 | @HiltViewModel
8 | class InputInfoViewModel @Inject constructor() : ViewModel() {
9 |
10 | val inputGender = MutableLiveData(" ") // 최초상태를 의미하는 하나의 공백 삽입
11 | val inputAge = MutableLiveData(" ")
12 | val inputSense = MutableLiveData(" ")
13 | val isGenderSelected: LiveData = // 빈칸인지 아닌지 확인하여 아이템 선택이 취소되었는지 관찰하기 위함
14 | Transformations.map(inputGender) { it ->
15 | it.isNotEmpty()
16 | }
17 | val isAgeSelected: LiveData = Transformations.map(inputAge) { it ->
18 | it.isNotEmpty()
19 | }
20 | val isSenseSelected: LiveData = Transformations.map(inputSense) { it ->
21 | it.isNotEmpty()
22 | }
23 | val isGenderSuccess: LiveData = // "한칸 공백도 아니고 빈칸도 아님 -> 아이템 선택 성공" 여부를 관찰하기 위함
24 | Transformations.map(inputGender) { it ->
25 | !(it.equals(" ") || it.equals(""))
26 | }
27 | val isAgeSuccess: LiveData = Transformations.map(inputAge) { it ->
28 | !(it.equals(" ") || it.equals(""))
29 | }
30 | val isSenseSuccess: LiveData = Transformations.map(inputSense) { it ->
31 | !(it.equals(" ") || it.equals(""))
32 | }
33 |
34 | fun getGender(): String { // getter
35 | return inputGender.value!!
36 | }
37 |
38 | fun setGender(gender: String) { // setter
39 | inputGender.value = gender
40 | }
41 |
42 | fun getAge(): String {
43 | return inputAge.value!!
44 | }
45 |
46 | fun setAge(age: String) {
47 | inputAge.value = age
48 | }
49 |
50 | fun getSense(): String {
51 | return inputSense.value!!
52 | }
53 |
54 | fun setSense(sense: String) {
55 | inputSense.value = sense
56 | }
57 |
58 | fun checkAllInputFiled(): Boolean { // 모든 정보가 입력되면 다음 버튼을 활성화시키기 위한 함수
59 | return (isGenderSuccess.value!! && isAgeSuccess.value!! && isSenseSuccess.value!!)
60 | }
61 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/presentation/setting/view/SettingFragment.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.presentation.setting.view
2 |
3 | import android.content.Intent
4 | import android.os.Bundle
5 | import android.view.View
6 | import org.shortweather.R
7 | import org.shortweather.databinding.FragmentSettingBinding
8 | import org.shortweather.presentation.alarmsetting.view.AlarmSettingActivity
9 | import org.shortweather.presentation.othertimesetting.view.OtherTimeSettingActivity
10 | import org.shortweather.presentation.waketimesetting.view.WakeTimeSettingActivity
11 | import org.shortweather.util.binding.BindingFragment
12 |
13 | class SettingFragment :
14 | BindingFragment(R.layout.fragment_setting) {
15 |
16 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
17 | super.onViewCreated(view, savedInstanceState)
18 |
19 | setOnClickListener()
20 | }
21 |
22 | fun setOnClickListener() {
23 | binding.layoutSettingTime.setOnClickListener {
24 | val intent = Intent(context, OtherTimeSettingActivity::class.java)
25 | startActivity(intent)
26 | }
27 | binding.layoutSettingAlarm.setOnClickListener {
28 | val intent = Intent(context, AlarmSettingActivity::class.java)
29 | startActivity(intent)
30 | }
31 | binding.layoutSettingWakeUp.setOnClickListener {
32 | val intent = Intent(context, WakeTimeSettingActivity::class.java)
33 | startActivity(intent)
34 | }
35 | }
36 |
37 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/presentation/splash/SplashActivity.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.presentation.splash
2 |
3 | import android.content.Intent
4 | import android.os.Bundle
5 | import android.os.Handler
6 | import android.os.Looper
7 | import androidx.activity.viewModels
8 | import dagger.hilt.android.AndroidEntryPoint
9 | import org.shortweather.R
10 | import org.shortweather.databinding.ActivitySplashBinding
11 | import org.shortweather.presentation.MainActivity
12 | import org.shortweather.presentation.input.view.InputInfoActivity
13 | import org.shortweather.presentation.input.viewmodel.InputTimeViewModel
14 | import org.shortweather.util.Constants.SUCCESS_200
15 | import org.shortweather.util.Constants.FAILURE
16 | import org.shortweather.util.Constants.HTTP_EXCEPTION_400
17 | import org.shortweather.util.Constants.HTTP_EXCEPTION_401
18 | import org.shortweather.util.Constants.HTTP_EXCEPTION_500
19 | import org.shortweather.util.EventObserver
20 | import org.shortweather.util.ShortWeatherSharedPreference
21 | import org.shortweather.util.binding.BindingActivity
22 | import org.shortweather.util.extension.showToast
23 |
24 | @AndroidEntryPoint
25 | class SplashActivity : BindingActivity(R.layout.activity_splash) {
26 | private val viewModel by viewModels()
27 |
28 | override fun onCreate(savedInstanceState: Bundle?) {
29 | super.onCreate(savedInstanceState)
30 | viewModel.setDeviceToken(ShortWeatherSharedPreference.getDeviceToken(this)) // 디바이스 토큰 설정
31 | setObservers()
32 | Handler(Looper.getMainLooper()).postDelayed({
33 | viewModel.searchUser() // 디바이스 토큰을 서버에 전송하여 유저 조회
34 | }, SPLASH_TIME)
35 | }
36 |
37 | private fun setObservers() {
38 | viewModel.searchUserEvent.observe( // 유저 조회 성공 시 Main으로, 실패 시 정보입력으로
39 | this, EventObserver { code ->
40 | when (code) {
41 | SUCCESS_200 -> {
42 | if (viewModel.getIsExist()) {
43 | startActivity(Intent(this, MainActivity::class.java))
44 | } else {
45 | startActivity(Intent(this, InputInfoActivity::class.java))
46 | }
47 | finish()
48 | }
49 | HTTP_EXCEPTION_400 -> showToast(getString(R.string.wait_server_error))
50 | HTTP_EXCEPTION_401 -> showToast(getString(R.string.wait_server_error))
51 | HTTP_EXCEPTION_500 -> showToast(getString(R.string.wait_server_error))
52 | FAILURE -> showToast(getString(R.string.http_server_error))
53 | }
54 | })
55 | viewModel.accessTokenEvent.observe( // 유저 조회 성공하면 액세스토큰 기기에 저장
56 | this, EventObserver { accessToken ->
57 | if (accessToken != null) {
58 | ShortWeatherSharedPreference.setAccessToken(this, accessToken)
59 | }
60 | })
61 | }
62 |
63 | companion object {
64 | private const val SPLASH_TIME: Long = 2800
65 | }
66 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/presentation/todayweathercontainer/OnPageDownClickListener.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.presentation.todayweathercontainer
2 |
3 | interface OnPageDownClickListener {
4 | fun pageDown()
5 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/presentation/todayweathercontainer/adapter/TodayWeatherContainerAdapter.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.presentation.todayweathercontainer.adapter
2 |
3 | import androidx.fragment.app.Fragment
4 | import androidx.fragment.app.FragmentActivity
5 | import androidx.viewpager2.adapter.FragmentStateAdapter
6 |
7 | class TodayWeatherContainerAdapter(
8 | private val fragments: List,
9 | fragmentActivity: FragmentActivity
10 | ) : FragmentStateAdapter(fragmentActivity) {
11 | override fun getItemCount(): Int = fragments.size
12 |
13 | override fun createFragment(position: Int): Fragment = fragments[position]
14 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/presentation/todayweathercontainer/view/TodayWeatherContainerFragment.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.presentation.todayweathercontainer.view
2 |
3 | import android.os.Bundle
4 | import android.view.View
5 | import androidx.fragment.app.viewModels
6 | import dagger.hilt.android.AndroidEntryPoint
7 | import org.shortweather.R
8 | import org.shortweather.databinding.FragmentTodayWeatherContainerBinding
9 | import org.shortweather.presentation.customweather.view.CustomWeatherFragment
10 | import org.shortweather.presentation.todayweather.view.TodayWeatherFragment
11 | import org.shortweather.presentation.todayweathercontainer.OnPageDownClickListener
12 | import org.shortweather.presentation.todayweathercontainer.adapter.TodayWeatherContainerAdapter
13 | import org.shortweather.presentation.todayweathercontainer.viewmodel.TodayWeatherContainerViewModel
14 | import org.shortweather.util.binding.BindingFragment
15 |
16 | @AndroidEntryPoint
17 | class TodayWeatherContainerFragment :
18 | BindingFragment(R.layout.fragment_today_weather_container) {
19 | private val viewModel: TodayWeatherContainerViewModel by viewModels()
20 | private val todayWeatherFragment = TodayWeatherFragment()
21 | private val customWeatherFragment = CustomWeatherFragment()
22 |
23 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
24 | super.onViewCreated(view, savedInstanceState)
25 |
26 | setAdapter()
27 | setOnPageDownClickListener()
28 | }
29 |
30 | private fun setAdapter() {
31 | binding.vpTodayWeatherContainer.adapter = TodayWeatherContainerAdapter(
32 | listOf(todayWeatherFragment, customWeatherFragment),
33 | requireActivity()
34 | )
35 | }
36 |
37 | private fun setOnPageDownClickListener() {
38 | todayWeatherFragment.setOnPageDownClickListener(object : OnPageDownClickListener {
39 | override fun pageDown() {
40 | binding.vpTodayWeatherContainer.currentItem = 1
41 | }
42 | })
43 | }
44 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/presentation/todayweathercontainer/viewmodel/TodayWeatherContainerViewModel.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.presentation.todayweathercontainer.viewmodel
2 |
3 | import androidx.lifecycle.ViewModel
4 | import dagger.hilt.android.lifecycle.HiltViewModel
5 | import javax.inject.Inject
6 |
7 | @HiltViewModel
8 | class TodayWeatherContainerViewModel @Inject constructor() : ViewModel() {
9 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/presentation/waketimesetting/view/WakeTimeSettingActivity.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.presentation.waketimesetting.view
2 |
3 | import android.os.Bundle
4 | import androidx.activity.viewModels
5 | import dagger.hilt.android.AndroidEntryPoint
6 | import org.shortweather.R
7 | import org.shortweather.databinding.ActivityWakeTimeSettingBinding
8 | import org.shortweather.presentation.input.view.BottomSheetTimeFragment
9 | import org.shortweather.presentation.input.viewmodel.InputTimeViewModel
10 | import org.shortweather.util.EventObserver
11 | import org.shortweather.util.binding.BindingActivity
12 | import org.shortweather.util.extension.setOnThrottleClickListener
13 |
14 | @AndroidEntryPoint
15 | class WakeTimeSettingActivity :
16 | BindingActivity(R.layout.activity_wake_time_setting) {
17 | private val viewModel by viewModels()
18 | private var beforeTime = " "
19 |
20 | override fun onCreate(savedInstanceState: Bundle?) {
21 | super.onCreate(savedInstanceState)
22 | binding.vm = viewModel // 데이터바인딩
23 | binding.lifecycleOwner = this
24 | binding.btnSettingWakeTimeCheck.isEnabled = false // 최초에는 확인 버튼의 Enable 상태 false
25 | setOnClickListener()
26 | setObservers()
27 | }
28 |
29 | private fun setObservers() {
30 | viewModel.isWakeDestroy.observe(this, EventObserver { isSuccess ->
31 | if (isSuccess && checkTimeChanged()) {
32 | binding.vSettingWakeTimeLine.setBackgroundResource(R.color.short_weather_blue)
33 | binding.btnSettingWakeTimeCheck.isEnabled = true
34 | } else { // 기상시간 변경 없이 단순히 선택되었다가 취소된 상황
35 | binding.vSettingWakeTimeLine.setBackgroundResource(R.color.short_weather_gray_1)
36 | binding.btnSettingWakeTimeCheck.isEnabled = false
37 | }
38 | })
39 | }
40 |
41 | private fun setOnClickListener() {
42 | // 확인 버튼을 누르면 MainActivity로 이동
43 | binding.btnSettingWakeTimeCheck.setOnThrottleClickListener {
44 | // 메인 액티비티의 설정 프래그먼트로 이동
45 | // 서버에 시간 전달
46 | finish()
47 | }
48 | binding.layoutSettingWakeTime.setOnThrottleClickListener { // 기상시간 선택 바텀시트 호출
49 | beforeTime = viewModel.timeWake.value!! // 호출 전 기상시간 저장
50 | binding.vSettingWakeTimeLine.setBackgroundResource(R.color.short_weather_blue)
51 | BottomSheetTimeFragment.newInstance("wake")
52 | .show(supportFragmentManager, BottomSheetTimeFragment.TAG)
53 | }
54 | }
55 |
56 | private fun checkTimeChanged(): Boolean { // 호출 전후 설정된 기상시간이 달라지면 true
57 | if (viewModel.timeWake.value == beforeTime) {
58 | return false
59 | }
60 | return true
61 | }
62 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/presentation/weeklyweather/adapter/WeeklyWeatherAdapter.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.presentation.weeklyweather.adapter
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 | import androidx.recyclerview.widget.ListAdapter
6 | import androidx.recyclerview.widget.RecyclerView
7 | import org.shortweather.data.model.WeeklyWeather
8 | import org.shortweather.databinding.ItemWeeklyWeatherBinding
9 | import org.shortweather.util.ItemDiffCallback
10 |
11 | class WeeklyWeatherAdapter :
12 | ListAdapter(
13 | ItemDiffCallback(
14 | onItemsTheSame = { oldItem, newItem -> oldItem == newItem },
15 | onContentsTheSame = { oldItem, newItem -> oldItem == newItem })
16 | ) {
17 | private lateinit var inflater: LayoutInflater
18 |
19 | override fun onCreateViewHolder(
20 | parent: ViewGroup,
21 | viewType: Int
22 | ): WeeklyWeatherViewHolder {
23 | if (!::inflater.isInitialized) {
24 | inflater = LayoutInflater.from(parent.context)
25 | }
26 | return WeeklyWeatherViewHolder(
27 | ItemWeeklyWeatherBinding.inflate(
28 | inflater,
29 | parent,
30 | false
31 | )
32 | )
33 | }
34 |
35 | override fun onBindViewHolder(holder: WeeklyWeatherViewHolder, position: Int) {
36 | holder.onBind(currentList[position])
37 | }
38 |
39 | class WeeklyWeatherViewHolder(
40 | private val binding: ItemWeeklyWeatherBinding
41 | ) : RecyclerView.ViewHolder(binding.root) {
42 | fun onBind(weather: WeeklyWeather) {
43 | binding.weeklyWeather = weather
44 | binding.executePendingBindings()
45 | }
46 | }
47 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/presentation/weeklyweather/view/WeeklyWeatherFragment.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.presentation.weeklyweather.view
2 |
3 | import android.os.Bundle
4 | import android.view.View
5 | import androidx.fragment.app.viewModels
6 | import org.shortweather.R
7 | import org.shortweather.databinding.FragmentWeeklyWeatherBinding
8 | import org.shortweather.presentation.weeklyweather.adapter.WeeklyWeatherAdapter
9 | import org.shortweather.presentation.weeklyweather.viewmodel.WeeklyWeatherViewModel
10 | import org.shortweather.util.binding.BindingFragment
11 |
12 | class WeeklyWeatherFragment :
13 | BindingFragment(R.layout.fragment_weekly_weather) {
14 | private val viewModel by viewModels()
15 | private val adapter = WeeklyWeatherAdapter()
16 |
17 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
18 | super.onViewCreated(view, savedInstanceState)
19 |
20 | initView()
21 | setAdapter()
22 | setOnRefreshListener()
23 | }
24 |
25 | private fun initView() {
26 | adapter.submitList(viewModel.getMockWeeklyWeatherList())
27 | }
28 |
29 | private fun setOnRefreshListener() {
30 | binding.srlWeeklyWeather.setOnRefreshListener {
31 | adapter.submitList(viewModel.getMockWeeklyWeatherList())
32 | binding.srlWeeklyWeather.isRefreshing = false
33 | }
34 | }
35 |
36 | private fun setAdapter() {
37 | binding.rvWeeklyWeather.adapter = adapter
38 | }
39 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/util/Constants.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.util
2 |
3 | object Constants {
4 | const val WEATHER = "weather"
5 | const val FINE_DUST = "fineDust"
6 | const val GENDER = "gender"
7 | const val AGE = "age"
8 | const val SENSE = "sense"
9 | const val WAKE = "wake"
10 | const val OUT = "out"
11 | const val RETURN = "return"
12 | const val SUCCESS_200 = 200
13 | const val SUCCESS_201 = 201
14 | const val HTTP_EXCEPTION_400 = 400
15 | const val HTTP_EXCEPTION_401 = 401
16 | const val HTTP_EXCEPTION_500 = 500
17 | const val FAILURE = 0
18 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/util/Event.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.util
2 |
3 | class Event(private val content: T) {
4 | private var hasBeenHandled = false
5 |
6 | fun getContentIfNotHandled(): T? {
7 | return if (hasBeenHandled) {
8 | null
9 | } else {
10 | hasBeenHandled = true
11 | content
12 | }
13 | }
14 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/util/EventObserver.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.util
2 |
3 | import androidx.lifecycle.Observer
4 |
5 | class EventObserver(private val onEventUnhandledContent: (T) -> Unit) : Observer> {
6 | override fun onChanged(event: Event?) {
7 | event?.getContentIfNotHandled()?.let {
8 | onEventUnhandledContent(it)
9 | }
10 | }
11 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/util/ItemDiffCallback.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.util
2 |
3 | import androidx.recyclerview.widget.DiffUtil
4 |
5 | class ItemDiffCallback(
6 | val onItemsTheSame: (T, T) -> Boolean,
7 | val onContentsTheSame: (T, T) -> Boolean,
8 | ) : DiffUtil.ItemCallback() {
9 | override fun areItemsTheSame(oldItem: T, newItem: T): Boolean = onItemsTheSame(oldItem, newItem)
10 | override fun areContentsTheSame(oldItem: T, newItem: T): Boolean =
11 | onContentsTheSame(oldItem, newItem)
12 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/util/OnThrottleClickListener.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.util
2 |
3 | import android.util.Log
4 | import android.view.View
5 |
6 | class OnThrottleClickListener( // 뷰의 중복 클릭을 막기 위한 리스너
7 | private val clickListener: View.OnClickListener,
8 | private val interval: Long = 500
9 | ) :
10 | View.OnClickListener {
11 |
12 | private var clickable = true
13 | // clickable 플래그를 이 클래스가 아니라 더 상위 클래스에 두면
14 | // 여러 뷰에 대한 중복 클릭 방지할 수 있다.
15 |
16 | override fun onClick(v: View?) {
17 | if (clickable) {
18 | clickable = false
19 | v?.run {
20 | postDelayed({
21 | clickable = true
22 | }, interval)
23 | clickListener.onClick(v)
24 | }
25 | } else {
26 | Log.d("tag", "waiting for a while")
27 | }
28 | }
29 |
30 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/util/ShortWeatherFirebaseMessagingService.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.util
2 |
3 | import com.google.firebase.messaging.FirebaseMessagingService
4 |
5 | class ShortWeatherFirebaseMessagingService : FirebaseMessagingService() {
6 | override fun onNewToken(token: String) {
7 | super.onNewToken(token)
8 | }
9 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/util/ShortWeatherSharedPreference.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.util
2 |
3 | import android.content.Context
4 | import android.content.SharedPreferences
5 | import com.google.firebase.messaging.FirebaseMessaging
6 |
7 | object ShortWeatherSharedPreference {
8 | fun setAccessToken(context: Context, token: String) { // 액세스 토큰 설정
9 | val sharedPreferences: SharedPreferences =
10 | context.getSharedPreferences("tokens", Context.MODE_PRIVATE)
11 | val editor: SharedPreferences.Editor = sharedPreferences.edit()
12 | editor.putString("AccessToken", token)
13 | editor.apply()
14 | }
15 |
16 | fun getAccessToken(context: Context): String { // 저장된 액세스 토큰 반환
17 | val prefs: SharedPreferences =
18 | context.getSharedPreferences("tokens", Context.MODE_PRIVATE)
19 | return prefs.getString("AccessToken", "").toString()
20 | }
21 |
22 | fun setDeviceToken(context: Context) { // 디바이스 토큰 설정
23 | FirebaseMessaging.getInstance().token.addOnSuccessListener {
24 | if (!it.isNullOrEmpty()) {
25 | val sharedPreferences: SharedPreferences =
26 | context.getSharedPreferences("tokens", Context.MODE_PRIVATE)
27 | val editor: SharedPreferences.Editor = sharedPreferences.edit()
28 | editor.putString("DeviceToken", it)
29 | editor.apply()
30 | }
31 | }
32 | }
33 |
34 | fun getDeviceToken(context: Context): String { // 저장된 디바이스 토큰 반환
35 | val prefs: SharedPreferences =
36 | context.getSharedPreferences("tokens", Context.MODE_PRIVATE)
37 | return prefs.getString("DeviceToken", "").toString()
38 | }
39 |
40 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/util/binding/BindingActivity.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.util.binding
2 |
3 | import android.os.Bundle
4 | import androidx.annotation.LayoutRes
5 | import androidx.appcompat.app.AppCompatActivity
6 | import androidx.databinding.DataBindingUtil
7 | import androidx.databinding.ViewDataBinding
8 |
9 | abstract class BindingActivity(@LayoutRes private val layoutRes: Int) :
10 | AppCompatActivity() {
11 | protected lateinit var binding: T
12 |
13 | override fun onCreate(savedInstanceState: Bundle?) {
14 | super.onCreate(savedInstanceState)
15 | binding = DataBindingUtil.setContentView(this, layoutRes)
16 | }
17 |
18 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/util/binding/BindingFragment.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.util.binding
2 |
3 | import android.os.Bundle
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import androidx.annotation.LayoutRes
8 | import androidx.databinding.DataBindingUtil
9 | import androidx.databinding.ViewDataBinding
10 | import androidx.fragment.app.Fragment
11 |
12 | abstract class BindingFragment(@LayoutRes private val layoutRes: Int) :
13 | Fragment() {
14 | private var _binding: T? = null
15 | protected val binding: T
16 | get() = requireNotNull(_binding) { "${this::class.java.simpleName} error." }
17 |
18 | override fun onCreateView(
19 | inflater: LayoutInflater,
20 | container: ViewGroup?,
21 | savedInstanceState: Bundle?
22 | ): View {
23 | _binding = DataBindingUtil.inflate(inflater, layoutRes, container, false)
24 | return binding.root
25 | }
26 |
27 | override fun onDestroyView() {
28 | super.onDestroyView()
29 | _binding = null
30 | }
31 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/util/extension/ActivityExt.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.util.extension
2 |
3 | import android.view.View
4 | import androidx.annotation.IdRes
5 | import androidx.appcompat.app.AppCompatActivity
6 | import androidx.fragment.app.Fragment
7 | import androidx.fragment.app.commit
8 | import androidx.fragment.app.replace
9 |
10 | inline fun AppCompatActivity.replace(@IdRes frameId: Int) {
11 | supportFragmentManager.commit {
12 | replace(frameId)
13 | setReorderingAllowed(true)
14 | }
15 | }
16 |
17 | fun AppCompatActivity.hideKeyboard() {
18 | hideKeyboard(currentFocus ?: View(this))
19 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/util/extension/ContextExt.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.util.extension
2 |
3 | import android.app.Activity
4 | import android.content.Context
5 | import android.view.View
6 | import android.view.inputmethod.InputMethodManager
7 | import android.widget.Toast
8 |
9 | fun Context.hideKeyboard(view: View) {
10 | val inputMethodManager = getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
11 | inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0)
12 | }
13 |
14 | fun Context.showToast(message: String, isShort: Boolean = true) {
15 | Toast.makeText(this, message, if (isShort) Toast.LENGTH_SHORT else Toast.LENGTH_LONG).show()
16 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/util/extension/LiveDataExt.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.util.extension
2 |
3 | import androidx.lifecycle.LiveData
4 | import androidx.lifecycle.MediatorLiveData
5 |
6 | fun MediatorLiveData.addSourceList(
7 | vararg liveDataArgument: LiveData<*>,
8 | onChanged: () -> T
9 | ) {
10 | liveDataArgument.forEach {
11 | this.addSource(it) { value = onChanged() }
12 | }
13 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/shortweather/util/extension/ViewExt.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather.util.extension
2 |
3 | import android.view.View
4 | import org.shortweather.util.OnThrottleClickListener
5 |
6 | fun View.setOnThrottleClickListener(action: (v: View) -> Unit) {
7 | val listener = View.OnClickListener { action(it) }
8 | setOnClickListener(OnThrottleClickListener(listener))
9 | }
10 |
11 | // with interval setting
12 | fun View.setOnThrottleClickListener(action: (v: View) -> Unit, interval: Long) {
13 | val listener = View.OnClickListener { action(it) }
14 | setOnClickListener(OnThrottleClickListener(listener, interval))
15 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/img_clear_day.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-hdpi/img_clear_day.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/img_clear_night.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-hdpi/img_clear_night.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/img_cloudy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-hdpi/img_cloudy.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/img_lightrain.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-hdpi/img_lightrain.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/img_lightsnow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-hdpi/img_lightsnow.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/img_lotcloud_day.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-hdpi/img_lotcloud_day.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/img_lotcloud_night.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-hdpi/img_lotcloud_night.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/img_rain.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-hdpi/img_rain.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/img_rainsnow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-hdpi/img_rainsnow.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/img_shower.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-hdpi/img_shower.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/img_snow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-hdpi/img_snow.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/img_snowdrifting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-hdpi/img_snowdrifting.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/img_clear_day.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xhdpi/img_clear_day.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/img_clear_night.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xhdpi/img_clear_night.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/img_cloudy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xhdpi/img_cloudy.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/img_lightrain.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xhdpi/img_lightrain.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/img_lightsnow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xhdpi/img_lightsnow.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/img_lotcloud_day.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xhdpi/img_lotcloud_day.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/img_lotcloud_night.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xhdpi/img_lotcloud_night.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/img_rain.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xhdpi/img_rain.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/img_rainsnow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xhdpi/img_rainsnow.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/img_shower.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xhdpi/img_shower.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/img_snow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xhdpi/img_snow.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/img_snowdrifting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xhdpi/img_snowdrifting.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/img_clear_day.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xxhdpi/img_clear_day.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/img_clear_night.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xxhdpi/img_clear_night.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/img_cloudy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xxhdpi/img_cloudy.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/img_lightrain.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xxhdpi/img_lightrain.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/img_lightsnow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xxhdpi/img_lightsnow.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/img_lotcloud_day.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xxhdpi/img_lotcloud_day.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/img_lotcloud_night.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xxhdpi/img_lotcloud_night.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/img_rain.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xxhdpi/img_rain.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/img_rainsnow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xxhdpi/img_rainsnow.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/img_shower.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xxhdpi/img_shower.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/img_snow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xxhdpi/img_snow.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/img_snowdrifting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xxhdpi/img_snowdrifting.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/img_clear_day.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xxxhdpi/img_clear_day.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/img_clear_night.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xxxhdpi/img_clear_night.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/img_cloudy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xxxhdpi/img_cloudy.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/img_lightrain.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xxxhdpi/img_lightrain.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/img_lightsnow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xxxhdpi/img_lightsnow.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/img_lotcloud_day.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xxxhdpi/img_lotcloud_day.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/img_lotcloud_night.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xxxhdpi/img_lotcloud_night.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/img_rain.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xxxhdpi/img_rain.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/img_rainsnow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xxxhdpi/img_rainsnow.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/img_shower.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xxxhdpi/img_shower.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/img_snow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xxxhdpi/img_snow.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/img_snowdrifting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable-xxxhdpi/img_snowdrifting.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_bad_dust.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_blue_circle.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_blue_newsflash.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_bottom_sheet.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_bottom_sheet_btn_blue.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_bottom_sheet_btn_gray.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_cloud.xml:
--------------------------------------------------------------------------------
1 |
7 |
9 |
10 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_day.xml:
--------------------------------------------------------------------------------
1 |
7 |
9 |
10 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_fog.xml:
--------------------------------------------------------------------------------
1 |
7 |
9 |
10 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_good_dust.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_gray_circle.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_night.xml:
--------------------------------------------------------------------------------
1 |
7 |
9 |
10 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_nomal_dust.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_rain.xml:
--------------------------------------------------------------------------------
1 |
7 |
9 |
10 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_red_newsflash.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_snow.xml:
--------------------------------------------------------------------------------
1 |
7 |
9 |
10 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_today_weather_description.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_today_weather_sub_description.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_today_weather_toast.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_windy.xml:
--------------------------------------------------------------------------------
1 |
7 |
9 |
10 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_worst_dust.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_yellow_newsflash.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_yellowdust.xml:
--------------------------------------------------------------------------------
1 |
7 |
9 |
10 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/btn_input_info.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_add.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_bottom_sheet_drag_view.xml:
--------------------------------------------------------------------------------
1 |
6 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_clear_day.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
9 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_clear_night.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_clothes.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_cloudy.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_dust_bad.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
9 |
12 |
15 |
18 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_dust_good.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
9 |
12 |
16 |
20 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_dust_normal.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
9 |
12 |
15 |
18 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_dust_worst.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
9 |
12 |
16 |
19 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_expand.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_expand_down.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_expand_red.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_expand_right.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_fog.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
13 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_hail.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
14 |
18 |
21 |
24 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_hamberger.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_heavyrain.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
9 |
13 |
17 |
21 |
25 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_humidity.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_lightning.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
9 |
13 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_lightrain.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
9 |
13 |
17 |
21 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_littlecloud_day.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_littlecloud_night.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_location.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
9 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_lotcloud_day.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
9 |
13 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_lotcloud_night.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_next_btn.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_precipitation_1.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
12 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_precipitation_10.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
9 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_precipitation_2.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
12 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_precipitation_3.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
12 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_precipitation_4.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
12 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_precipitation_5.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
12 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_precipitation_6.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
12 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_precipitation_7.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
12 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_precipitation_8.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
12 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_precipitation_9.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
12 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_rain.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
9 |
13 |
17 |
21 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_setting.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_shower.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
9 |
13 |
17 |
21 |
25 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_snow.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_snowdrifting.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_sunrise.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_sunset.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_toast.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_today.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
9 |
10 |
13 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_week.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_weekly_weather_example.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_windy.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
14 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_yellowdust.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
14 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/img_clear_day.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable/img_clear_day.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/img_clear_night.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable/img_clear_night.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/img_cloudy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable/img_cloudy.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/img_lightrain.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable/img_lightrain.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/img_lightsnow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable/img_lightsnow.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/img_lotcloud_day.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable/img_lotcloud_day.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/img_lotcloud_night.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable/img_lotcloud_night.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/img_rain.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable/img_rain.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/img_rainsnow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable/img_rainsnow.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/img_shower.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable/img_shower.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/img_snow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable/img_snow.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/img_snowdrifting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/drawable/img_snowdrifting.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/selector_input_btn_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/selector_input_btn_text_color.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/font/pretendard_black.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/font/pretendard_black.otf
--------------------------------------------------------------------------------
/app/src/main/res/font/pretendard_bold.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/font/pretendard_bold.otf
--------------------------------------------------------------------------------
/app/src/main/res/font/pretendard_extrabold.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/font/pretendard_extrabold.otf
--------------------------------------------------------------------------------
/app/src/main/res/font/pretendard_extralight.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/font/pretendard_extralight.otf
--------------------------------------------------------------------------------
/app/src/main/res/font/pretendard_light.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/font/pretendard_light.otf
--------------------------------------------------------------------------------
/app/src/main/res/font/pretendard_medium.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/font/pretendard_medium.otf
--------------------------------------------------------------------------------
/app/src/main/res/font/pretendard_regular.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/font/pretendard_regular.otf
--------------------------------------------------------------------------------
/app/src/main/res/font/pretendard_semibold.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/font/pretendard_semibold.otf
--------------------------------------------------------------------------------
/app/src/main/res/font/pretendard_thin.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/font/pretendard_thin.otf
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_splash.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
15 |
16 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/bottom_sheet_content.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
22 |
23 |
31 |
32 |
39 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/bottom_sheet_time_content.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
21 |
22 |
28 |
29 |
38 |
39 |
54 |
55 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_today_weather_container.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_bottom_sheet.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_custom_weather_precipitation.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
10 |
11 |
12 |
16 |
17 |
28 |
29 |
39 |
40 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_custom_weather_weather.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
10 |
11 |
12 |
16 |
17 |
28 |
29 |
40 |
41 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_drawer_header.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
18 |
19 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_today_weather_fine_dust.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
10 |
11 |
12 |
15 |
16 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_today_weather_newsflash.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
10 |
11 |
12 |
15 |
16 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_today_weather_ultrafine_dust.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
10 |
11 |
12 |
15 |
16 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_drawer.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_tool_bar.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/mipmap-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_short_weather.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/mipmap-hdpi/ic_short_weather.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/mipmap-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_short_weather.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/mipmap-mdpi/ic_short_weather.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_short_weather.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/mipmap-xhdpi/ic_short_weather.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_short_weather.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/mipmap-xxhdpi/ic_short_weather.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_short_weather.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/app/src/main/res/mipmap-xxxhdpi/ic_short_weather.png
--------------------------------------------------------------------------------
/app/src/main/res/values-night/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | #FFBB86FC
5 | #FF6200EE
6 | #FF3700B3
7 | #FF03DAC5
8 | #FF018786
9 | #FF000000
10 | #FFFFFFFF
11 |
12 |
13 | #000000
14 | #2F2F2F
15 | #717171
16 | #7D7F84
17 | #919499
18 | #A7A7A7
19 | #DCDCDC
20 | #EBEBEB
21 | #F2F2F2
22 | #F8F8F8
23 | #FFFFFF
24 | #5C7EFF
25 | #FFF6DD
26 | #FF8383
27 | #E0F0FB
28 | #9AC4F3
29 | #7390FF
30 | #CDF1D5
31 | #59B06D
32 | #FFEFB6
33 | #E0AE56
34 | #FFC700
35 | #FF974B
36 | #FFDADC
37 | #EDC9C9
38 | #E4626A
39 | #8B3939
40 | #B774DA
41 | #FF4F4F
42 | #73FFFFFF
43 |
--------------------------------------------------------------------------------
/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/backup_rules.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/data_extraction_rules.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
12 |
13 |
19 |
--------------------------------------------------------------------------------
/app/src/test/java/org/shortweather/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package org.shortweather
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | buildscript {
3 | ext {
4 | activity_ktx_version = '1.6.0'
5 | fragment_ktx_version = '1.5.3'
6 | lifecycle_version = '2.5.1'
7 | retrofit_version = '2.9.0'
8 | okhttp_version = '4.10.0'
9 | kotlinx_serialization_version = '1.4.1'
10 | kotlinx_serialization_converter_version = '0.8.0'
11 | hilt_version = '2.44'
12 | dotsindicator_version = '4.3'
13 | lottie_version = '5.2.0'
14 | swipe_refresh_layout_version = '1.1.0'
15 | switch_button_version = '0.0.3@aar'
16 | fcm_version = '23.1.1'
17 | fb_messaging_version = '23.1.1'
18 | fb_bom_version = '31.1.1'
19 | }
20 | repositories {
21 | mavenCentral()
22 | google()
23 | }
24 |
25 | dependencies {
26 | classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_version"
27 | classpath 'com.google.gms:google-services:4.3.14'
28 | }
29 | }
30 |
31 | plugins {
32 | id 'com.android.application' version '7.3.0' apply false
33 | id 'com.android.library' version '7.3.0' apply false
34 | id 'org.jetbrains.kotlin.android' version '1.7.10' apply false
35 | id 'com.google.gms.google-services' version '4.3.10' apply false
36 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app's APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Kotlin code style for this project: "official" or "obsolete":
19 | kotlin.code.style=official
20 | # Enables namespacing of each library's R class so that its R class includes only the
21 | # resources declared in the library itself and none from the library's dependencies,
22 | # thereby reducing the size of the R class for that library
23 | android.nonTransitiveRClass=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TeamShortWeather/ShortWeather-AOS/5df67c7d835f3e3cac496e9410c14d9ba5a7b130/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Dec 29 21:42:18 KST 2022
2 | distributionBase=GRADLE_USER_HOME
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
4 | distributionPath=wrapper/dists
5 | zipStorePath=wrapper/dists
6 | zipStoreBase=GRADLE_USER_HOME
7 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | gradlePluginPortal()
4 | google()
5 | mavenCentral()
6 | }
7 | }
8 | dependencyResolutionManagement {
9 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
10 | repositories {
11 | google()
12 | mavenCentral()
13 | }
14 | }
15 | rootProject.name = "ShortWeather"
16 | include ':app'
17 |
--------------------------------------------------------------------------------