diff --git a/app/build.gradle b/app/build.gradle index 7e0b313..09b1548 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -56,6 +56,9 @@ dependencies { // Moshi implementation 'com.squareup.moshi:moshi-kotlin:1.13.0' + // Coil + implementation "io.coil-kt:coil:1.1.1" + testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' diff --git a/app/src/main/java/com/reyndev/simpliweather/BindingAdapter.kt b/app/src/main/java/com/reyndev/simpliweather/BindingAdapter.kt index e062398..3db725f 100644 --- a/app/src/main/java/com/reyndev/simpliweather/BindingAdapter.kt +++ b/app/src/main/java/com/reyndev/simpliweather/BindingAdapter.kt @@ -3,9 +3,11 @@ package com.reyndev.simpliweather import android.view.View import android.widget.ImageView import android.widget.TextView +import androidx.core.net.toUri import androidx.databinding.BindingAdapter import androidx.lifecycle.LiveData import androidx.recyclerview.widget.RecyclerView +import coil.load import com.reyndev.simpliweather.adapter.GeoAdapter import com.reyndev.simpliweather.data.GeoModel import com.reyndev.simpliweather.data.WeatherApiStatus @@ -36,4 +38,17 @@ fun apiStatus(imageView: ImageView, status: WeatherApiStatus) { imageView.setImageResource(R.drawable.ic_error) } } +} + +@BindingAdapter("imageUrl") +fun imageUrl(imageView: ImageView, icon: String?) { + icon?.let { + val imgUrl = "https://openweathermap.org/img/wn/${icon}@2x.png" + val imgUri = imgUrl.toUri().buildUpon().scheme("https").build() + + imageView.load(imgUri) { + placeholder(R.drawable.loading_animation) + error(R.drawable.default_weather) + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/reyndev/simpliweather/adapter/GeoAdapter.kt b/app/src/main/java/com/reyndev/simpliweather/adapter/GeoAdapter.kt index dfa3cf3..0c3c2f9 100644 --- a/app/src/main/java/com/reyndev/simpliweather/adapter/GeoAdapter.kt +++ b/app/src/main/java/com/reyndev/simpliweather/adapter/GeoAdapter.kt @@ -15,6 +15,11 @@ class GeoAdapter(private val clickListener: GeoListener) : RecyclerView.ViewHolder(binding.root) { fun bind(clickListener: GeoListener, geo: GeoModel) { + if (!geo.state.isNullOrBlank()) + binding.geoName.text = "${geo.name}, ${geo.state}" + else + binding.geoName.text = geo.name + binding.geo = geo binding.clickListener = clickListener binding.executePendingBindings() @@ -41,7 +46,7 @@ class GeoAdapter(private val clickListener: GeoListener) } override fun areContentsTheSame(oldItem: GeoModel, newItem: GeoModel): Boolean { - return (oldItem.lat == newItem.lat) && (oldItem.lon == newItem.lon) + return oldItem.state == newItem.state } } } diff --git a/app/src/main/java/com/reyndev/simpliweather/data/WeatherModel.kt b/app/src/main/java/com/reyndev/simpliweather/data/WeatherModel.kt index 82b3993..581b139 100644 --- a/app/src/main/java/com/reyndev/simpliweather/data/WeatherModel.kt +++ b/app/src/main/java/com/reyndev/simpliweather/data/WeatherModel.kt @@ -5,7 +5,8 @@ import com.squareup.moshi.Json data class GeoModel( val name: String, val lat: String, - val lon: String + val lon: String, + val state: String? ) data class WeatherModel( diff --git a/app/src/main/java/com/reyndev/simpliweather/data/WeatherViewModel.kt b/app/src/main/java/com/reyndev/simpliweather/data/WeatherViewModel.kt index 61ab57d..41e3196 100644 --- a/app/src/main/java/com/reyndev/simpliweather/data/WeatherViewModel.kt +++ b/app/src/main/java/com/reyndev/simpliweather/data/WeatherViewModel.kt @@ -30,7 +30,8 @@ class WeatherViewModel : ViewModel() { val newGeo = GeoModel( "Special Capital Region of Jakarta", (-6.1753942).toString(), - (106.827183).toString() + (106.827183).toString(), + null ) _location.value = newGeo @@ -43,7 +44,7 @@ class WeatherViewModel : ViewModel() { _status.value = WeatherApiStatus.LOADING try { - _geo.value = WeatherApiService.geoService.getGeo( + _geo.value = WeatherApiService.weatherService.getGeo( name, 5, appId diff --git a/app/src/main/java/com/reyndev/simpliweather/network/WeatherApiService.kt b/app/src/main/java/com/reyndev/simpliweather/network/WeatherApiService.kt index a8d74c7..f2d4c60 100644 --- a/app/src/main/java/com/reyndev/simpliweather/network/WeatherApiService.kt +++ b/app/src/main/java/com/reyndev/simpliweather/network/WeatherApiService.kt @@ -7,36 +7,29 @@ import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory import retrofit2.Retrofit import retrofit2.converter.moshi.MoshiConverterFactory import retrofit2.http.GET +import retrofit2.http.Path import retrofit2.http.Query -private const val GEO_URL = "https://api.openweathermap.org/geo/1.0/" -private const val WEATHER_URL = "https://api.openweathermap.org/data/3.0/" +private const val BASE_URL = "https://api.openweathermap.org/" val moshi = Moshi.Builder() .add(KotlinJsonAdapterFactory()) .build() -val retroGeo = Retrofit.Builder() +val retrofit = Retrofit.Builder() .addConverterFactory(MoshiConverterFactory.create(moshi)) - .baseUrl(GEO_URL) + .baseUrl(BASE_URL) .build() -val retroWeather = Retrofit.Builder() - .addConverterFactory(MoshiConverterFactory.create(moshi)) - .baseUrl(WEATHER_URL) - .build() - -interface GeoApi { - @GET("direct") +interface WeatherApi { + @GET("geo/1.0/direct") suspend fun getGeo( @Query("q") name: String, @Query("limit") limit: Int, @Query("appid") id: String ): List -} -interface WeatherApi { - @GET("onecall") + @GET("data/3.0/onecall") suspend fun getWeather( @Query("lat") lat: Double, @Query("lon") lon: Double, @@ -47,11 +40,7 @@ interface WeatherApi { } object WeatherApiService { - val geoService: GeoApi by lazy { - retroGeo.create(GeoApi::class.java) - } - val weatherService: WeatherApi by lazy { - retroWeather.create(WeatherApi::class.java) + retrofit.create(WeatherApi::class.java) } } \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_geo_search.xml b/app/src/main/res/layout/fragment_geo_search.xml index 6b4e4e2..0950690 100644 --- a/app/src/main/res/layout/fragment_geo_search.xml +++ b/app/src/main/res/layout/fragment_geo_search.xml @@ -86,8 +86,8 @@ + app:layout_constraintTop_toBottomOf="@id/city_search" + app:imageUrl="@{viewModel.weather.current.weather[0].icon}"/>