kotlin 如何访问ViewModel类中的JSON文件?

7uhlpewt  于 2023-03-19  发布在  Kotlin
关注(0)|答案(2)|浏览(209)

我正在尝试在位于“assets”的本地文件中加载带有JSON数据的RecyclerView。
活动:

class RecipesActivity : AppCompatActivity(), RecipeAdapter.RecipeItemListener {

private lateinit var binding : ActivityRecipesBinding

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivityRecipesBinding.inflate(layoutInflater)
    setContentView(binding.root)

    setSupportActionBar(binding.mainToolBar.toolbar)
    supportActionBar?.setDisplayShowTitleEnabled(false)

    val viewModel : RecipeViewModel by viewModels()
    viewModel.getRecipes().observe(this) {
        binding.recipesRecyclerView.adapter = RecipeAdapter(this, it, this)
    }
}

适配器:

class RecipeAdapter (val context : Context,
                 private val recipes : List<Recipe>,
                 private val itemListener : RecipeItemListener) : RecyclerView.Adapter<RecipeAdapter.RecipeViewHolder>() {

   inner class RecipeViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView) {
       var recipeTextView = itemView.findViewById<TextView>(R.id.recipeTextView)
   }

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecipeViewHolder {
    val inflator = LayoutInflater.from(parent.context)
    val view = inflator.inflate(R.layout.item_recipe, parent, false)
    return RecipeViewHolder(view)
}

override fun onBindViewHolder(viewHolder: RecipeViewHolder, position: Int) {
    val recipe = recipes[position]
    with (viewHolder) {
        recipeTextView.text = recipe.dish

        itemView.setOnClickListener {
            itemListener.recipeSelected(recipe)
        }
    }
}

override fun getItemCount(): Int {
    return recipes.size
}

interface RecipeItemListener {
    fun recipeSelected(recipe : Recipe)
}

视图模型:

class RecipeViewModel : ViewModel() {
private var recipes = MutableLiveData<List<Recipe>>()

init {
    val gson = Gson()
    val inputStream: InputStream = assets.open("recipes.json")

    val jsonStr = inputStream.bufferedReader().use { it.readText() }

    val recipeList = gson.fromJson(jsonStr, Array<Recipe>::class.java).toList()
    recipes.value = recipeList
    Log.i("json string", "${recipeList.toString()}")
}

fun getRecipes() : LiveData<List<Recipe>> {
    return recipes
}

除了获取数据之外,一切都正常,只是不知道如何做到这一点。我试着将上下文作为参数传递给构造函数,但我不知道还需要更新哪里,因为它说没有空的构造函数存在。我添加了一个空的构造函数,但它使recyclerview为空。

dsekswqp

dsekswqp1#

我使用这个代码从资产加载JSON列表:

private val dataType: Type by lazy {
         object : TypeToken<Collection<DATA?>?>() {}.type
     }

    init {
         val gson = Gson()
         val assetManager = context.assets // probably same as your assets

         val data = runCatching {
             val inputStream = assetManager.open("data_file.json")
             val reader = JsonReader(InputStreamReader(inputStream))

             val quotes: Collection<DATA> =
                 gson.fromJson(
                     reader,
                     storyMissionType
                 )

             inputStream.close()
             reader.close()

             quotes.toList()
         }.getOrDefault(emptyList())
    }
vom3gejh

vom3gejh2#

首先,您不需要在每次LiveData更改时初始化RecipeAdapter:

viewModel.getRecipes().observe(this) {
    binding.recipesRecyclerView.adapter = RecipeAdapter(this, it, this)
}

您可以拨打:

binding.recipesRecyclerView.adapter?.notifyDataSetChanged()

并在此之前初始化它。第二次在RecyclerView中检查:

app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"

相关问题