-
Notifications
You must be signed in to change notification settings - Fork 0
[Task 2 Walkthrough]: Load In season Produce for California in June
Detailed Walkthrough. Only consult this page if you are having difficulty completing the task or wish to check your work.
seasonal_metadata.json: https://drive.google.com/file/d/1w5BQOje4-Hqk586gG5OWDH0O_LfPtnFo/view?usp=sharing
seasonal_california.json: https://drive.google.com/open?id=1D0NgqCuaQAr0ilATxE7uulXtgn0rSMVb
Check out both files and see the type of data they have and how they are connected.
// https://github.com/google/gson
implementation 'com.google.code.gson:gson:2.8.2'
3. Fill in your ProduceItem model to mimic the JSON files. Allow GSON to deserialize your JSON into fields using @SerializedName
for your client models.
Your data class will look similar to this:
data class ProduceItem(
@SerializedName("ID") val id: String,
@SerializedName("Name") val name: String,
@SerializedName("Type") val type: String,
@SerializedName("Description") val description: String
)
Declare the strings for the files:
val SEASONAL_METADATA_JSON = "seasonal_metadata.json"
val SEASONAL_CALIFORNIA_JSON = "seasonal_california.json"
Use AssetManager to open file, and parse JSON:
fun getProduceItemsFromJSON(context: Context): List<ProduceItem> {
val assetManager = context.assets
val metadataFile = assetManager.open(SEASONAL_METADATA_JSON)
val metadata = metadataFile.readBytes().toString(Charset.defaultCharset())
val stateJSONFile = assetManager.open(SEASONAL_CALIFORNIA_JSON)
val stateJSONString = stateJSONFile.readBytes().toString(Charset.defaultCharset())
val produceItems = parseJSONFile(metadata, stateJSONString)
return produceItems
}
In order to parse the JSON file, use GSONBuilder:
private fun parseJSONFile(jsonString: String, stateJSONString: String): List<ProduceItem> {
val gsonBuilder = GsonBuilder().setPrettyPrinting().create()
//parse seasonal_metadata
val produceItemList: List<ProduceItem> = gsonBuilder.fromJson(jsonString, object :
TypeToken<List<ProduceItem>>() {}.type)
return produceItemList
}
5. Populate your RecyclerView with ProduceItems in June for California. All produce names and descriptions are in seasonal_metadata, and California items are in seasonal_california. You can connect them by id. Hint: try map and filter
In MainActivity’s onCreate(), replace fake data with a call to getProduceItemsFromJSON()
//retrieve data from json files
val items = getProduceItemsFromJSON(this)
At this point, if you run the app, you should be able to see a list of all of the ProduceItems from the metadata file.
Now, we want to only see produce in June for California, so let's deserialize more data classes. Mimic the json structure, and you will be able to come up with data classes that look similar to this:
data class ProduceByState(
@SerializedName("ID") val id: String,
@SerializedName("months") val months: ProduceMonth
)
data class ProduceMonth(
@SerializedName("January") val january: Boolean,
@SerializedName("February") val february: Boolean,
@SerializedName("March") val march: Boolean,
@SerializedName("April") val april: Boolean,
@SerializedName("May") val may: Boolean,
@SerializedName("June") val june: Boolean,
@SerializedName("July") val july: Boolean,
@SerializedName("August") val august: Boolean,
@SerializedName("September") val september: Boolean,
@SerializedName("October") val october: Boolean,
@SerializedName("November") val november: Boolean,
@SerializedName("December") val december: Boolean
)
Then, fix your parsing method to parse seasonal_california and apply a map/filter to only show California items in June.
private fun parseJSONFile(jsonString: String, stateJSONString: String): List<ProduceItem> {
val gsonBuilder = GsonBuilder().setPrettyPrinting().create()
//parse seasonal_metadata
val produceItemList: List<ProduceItem> = gsonBuilder.fromJson(jsonString, object :
TypeToken<List<ProduceItem>>() {}.type)
//parse seasonal_california
val californiaProduceIds: List<ProduceByState> = gsonBuilder.fromJson(stateJSONString, object :
TypeToken<List<ProduceByState>>() {}.type)
val juneIds = californiaProduceIds.filter { it -> it.months.june }
.map { it -> it.id }
val juneProduce = produceItemList.filter { it -> (juneIds.contains(it.id)) }
return juneProduce
}
Run the app, and you should see a list of California produce items with either "Fruit" or "Vegetable" produce type.