Search code examples
androidjsonandroid-fragmentsparcelable

How to pass objects from activity to fragments?


I would like to pass objects (that I got through Retrofit) to fragments. I heard of 2 methods, but I have problems with both. I am trying to pass a FullForecast object to my fragments.

  1. Use Parcelize. I implemented it on my class, but it conflicted with my constructor.

enter image description here

  1. I heard I could pass a Json string from the activity to fragment and then convert it to an object once inside the fragment. However, I could not get the Json string from my Json call. I tried Call<ResponseBody>, and did response.body().toString(), but didnt get a Json string

Here is my code

repository.getWeatherForecast(place,
                object : Callback<FullForecast> {
                    override fun onFailure(call: Call<FullForecast>?, t: Throwable?) {
                        println("onFailure")
                    }

                    override fun onResponse(call: Call<FullForecast>?, response: Response<FullForecast>?) {
                        if (response != null && response.isSuccessful && response.body() != null) {

                            forecastObj = response.body() as FullForecast
                            // Try to get Json string here
                        }
                    }
                })

@JsonClass(generateAdapter = true)
data class FullForecast(@Json(name = "list")
                        val forecastList: List<WeatherForecast>) {
}

@JsonClass(generateAdapter = true)
data class WeatherForecast(@Json(name = "main")
                           val weatherDetail: WeatherDetail,

                           @Json(name = "weather")
                           val weatherIcon: List<WeatherIcon>,

                           @Json(name = "dt_txt")
                           val date: String) {
}

@JsonClass(generateAdapter = true)
data class Place(@Json(name = "main")
                 val weatherDetail: WeatherDetail,

                 @Json(name = "weather")
                 val weatherIcon: List<WeatherIcon>,

                 @Json(name = "sys")
                 val countryDetail: CountryDetail,

                 @Json(name = "dt_txt")
                 var forecastDate: String = "",

                 val name: String,

                 var placeIdentifier: String = "",

                 var lastUpdated: String = "") {
}

@JsonClass(generateAdapter = true)
data class CountryDetail(val country: String) {
}

@JsonClass(generateAdapter = true)
data class WeatherDetail(@Json(name = "temp")
                         val temperature: Double,
                         val temp_min: Double,
                         val temp_max: Double) {
}

@JsonClass(generateAdapter = true)
data class WeatherIcon(val icon: String) {
}

Solution

  • You should implement Parcelize as below

      @Parcelize
      @JsonClass(generateAdapter = true)
      data class FullForecast(@Json(name = "list")
      val forecastList: List<WeatherForecast>) : Parcelable {
      }
    
      @Parcelize
      @JsonClass(generateAdapter = true)
      data class WeatherForecast(@Json(name = "main")
      val weatherDetail: WeatherDetail,
    
          @Json(name = "weather")
          val weatherIcon: List<WeatherIcon>,
    
          @Json(name = "dt_txt")
          val date: String) : Parcelable {
      }
    
      @Parcelize
      @JsonClass(generateAdapter = true)
      data class Place(@Json(name = "main")
      val weatherDetail: WeatherDetail,
    
          @Json(name = "weather")
          val weatherIcon: List<WeatherIcon>,
    
          @Json(name = "sys")
          val countryDetail: CountryDetail,
    
          @Json(name = "dt_txt")
          var forecastDate: String = "",
    
          val name: String,
    
          var placeIdentifier: String = "",
    
          var lastUpdated: String = "") : Parcelable {
      }
    
      @Parcelize
      @JsonClass(generateAdapter = true)
      data class CountryDetail(val country: String) : Parcelable {
      }
    
      @Parcelize
      @JsonClass(generateAdapter = true)
      data class WeatherDetail(@Json(name = "temp")
      val temperature: Double,
          val temp_min: Double,
          val temp_max: Double) : Parcelable {
      }
    
      @Parcelize
      @JsonClass(generateAdapter = true)
      data class WeatherIcon(val icon: String) : Parcelable {
      }
    

    If you face error:

    enter image description here

    This is a known bug in the IDE itself and you can ignore it, there’s nothing wrong with the code and it works as expected. You can keep track of the issue here.