android - Android:将 JSONArray 的值传递给新活动并让值引用不同的对象
问题描述
感谢您的耐心等待,我对 Android 开发非常陌生。我想构建一个从 JSON 文件中提取数据的简单应用程序。该应用程序的结构本质上是一个拥有他们独有数据(生日、报价)的人的列表,以及一个他们喜欢的食物列表,这些食物不是他们独有的,也可以被列表中的其他人使用。喜欢的食物的成分在被点击时会显示出来。
我已经获得了人们运作的初始列表视图,但我坚持如何让他们喜欢的食物列表显示为可以点击以显示其成分的列表项。例如,如何获取数组中的 Amy 喜欢的披萨,以显示 JSON 文件的“item”对象部分中包含的成分列表。
食品成分的当前筛选和预期结果:https ://imgur.com/YlO3GEb
JSON:
{
"person": [
{
"name": "Amy",
"birthday" : "November 20",
"likes" : [ "pizza", "mac and cheese", "orange juice" ],
"image" : "pathhere.png"
},
{
"name": "Mark",
"birthday" : "June 20",
"likes" : [ "pizza", "orange juice", "apple juice" ],
"image" : "pathhere.png"
},
{
"name": "Smith",
"birthday" : "April 10",
"likes" : [ "cheese" ],
"image" : "pathhere.png"
}
],
"item": [
{
"name": "pizza",
"ingredients" : [ "cheese", "dough", "tomato" ],
"image" : "pathhere.png"
},
{
"name": "mac and cheese",
"ingredients" : [ "cheese", "pasta" ],
"image" : "pathhere.png"
},
{
"name": "orange juice",
"ingredients" : [ "orange" ],
"image" : "pathhere.png"
},
{
"name": "apple juice",
"ingredients" : [ "apple" ],
"image" : "pathhere.png"
},
{
"name": "cheese",
"image" : "pathhere.png"
}
]
}
主要活动
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.widget.ListView
class MainActivity : AppCompatActivity() {
private lateinit var listView: ListView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
listView = findViewById<ListView>(R.id.person_list)
val personList = Person.getPersonFromFile("main.json", this)
val adapter = PersonAdapter(this, personList)
listView.adapter = adapter
val context = this
listView.setOnItemClickListener { _, _, position, _ ->
val selectedPerson = personList[position]
val detailIntent = PersonDetailActivity.newIntent(context, selectedPerson)
startActivity(detailIntent)
}
}
}
人物类
import android.content.Context
import org.json.JSONException
import org.json.JSONObject
class Person(
val name: String,
val birthday: String,
val likes: String
)
{
companion object {
fun getPersonFromFile(filename: String, context: Context): ArrayList<Person> {
val personList = ArrayList<Person>()
try {
val jsonString = loadJsonFromAsset("main.json", context)
val json = JSONObject(jsonString)
val person = json.getJSONArray("person")
(0 until person.length()).mapTo(personList) {
Person(
person.getJSONObject(it).getString("name"),
person.getJSONObject(it).getString("birthday"),
person.getJSONObject(it).getJSONArray("likes").toString()
)
}
} catch (e: JSONException) {
e.printStackTrace()
}
return personList
}
private fun loadJsonFromAsset(filename: String, context: Context): String? {
var json: String? = null
try {
val inputStream = context.assets.open(filename)
val size = inputStream.available()
val buffer = ByteArray(size)
inputStream.read(buffer)
inputStream.close()
json = String(buffer, Charsets.UTF_8)
} catch (ex: java.io.IOException) {
ex.printStackTrace()
return null
}
return json
}
}
}
PersonDetailActivity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.widget.ArrayAdapter
import android.widget.ListView
import kotlinx.android.synthetic.main.activity_person_detail.*
class PersonDetailActivity : AppCompatActivity() {
private lateinit var listView: ListView
companion object {
const val EXTRA_NAME = "name"
const val EXTRA_BIRTHDAY = "birthday"
const val EXTRA_LIKES = "likes"
fun newIntent(context: Context, person: Person): Intent {
val detailIntent = Intent(context, PersonDetailActivity::class.java)
detailIntent.putExtra(EXTRA_NAME, person.name)
detailIntent.putExtra(EXTRA_BIRTHDAY, person.birthday)
detailIntent.putExtra(EXTRA_LIKES, person.likes)
return detailIntent
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_person_detail)
val arrayAdapter: ArrayAdapter<*>
val name = intent.extras.getString(EXTRA_NAME)
val birthday = intent.extras.getString(EXTRA_BIRTHDAY)
val likes = intent.extras.getString(EXTRA_LIKES)
person_name.text = name
person_birthday.text = birthday
val likesArray = likes.split(",")
listView = findViewById<ListView>(R.id.person_likes)
arrayAdapter = ArrayAdapter(this, R.layout.basic_list_item, R.id.basic_list_text, likesArray)
listView.adapter = arrayAdapter
}
}
解决方案
我在下面的简单算法的帮助下添加了一个解决方案来概述您的问题:
//After clicking on spinner item, pass two string to next activity as Json String vai Intent.
//Inside listView.setOnItemClickListener
String liskesJsonStr = personList[position].getLikes() //Json string for person's like
String itemsListJson = mainJsonObj.getJsonArray("item").toString() //Json string for all ListItems
//Create Intent PersonDetailActivity and pass liskesJsonStr and itemsListJson as String.
//Instead of liskesJsonStr you can pass Person Object directly to PersonDetailActivity and get liskesJsonList there.
//Inside PersonDetailActivity (Assuming I have passed liskesJsonStr instead of Person object)
//Get person's Like List from liskesJsonStr
JsonArray personLikedListJson = JsonArray("liskesJsonStr from IntenT") //use personObj.getLikes() if passed person object
//Creating a hash map with food name as key and the Item object as value
Create Map<String, JsonObject> mapItem; //class variable
JsonArray itemListJson = JsonArray("itemsListJson from IntenT")
loop: 0 to itemListJson.lenght
mapItem.put(itemJson.getName(), itemListJson[position]);
//Use personLikedListJson to generate further spinner for Person's liked list so that you can see ingredients for the food after selection.
//So add create Person's liked food spinner here.....
//Inside listView.setOnItemClickListener for liked food
//Get food name: "foodName" using likedFoodObj.get(position) //Where likedFoodObj is the item object of the spinner
val likedItemJsonObj : JsonObject = mapItem.get(foodName)
var ingredientList = likedItemJsonObj.getJsonArray(ingredients);
//Now you as the ingredientList for the selected food item from person's liked food list.
//use this ingredientList for any further spinner you want to show.
如果有什么让您感到困惑,请告诉我。