如何从 Assets 文件夹中解析 StickyHeader RecyclerView 中的 json 数据

Posted

技术标签:

【中文标题】如何从 Assets 文件夹中解析 StickyHeader RecyclerView 中的 json 数据【英文标题】:How to parse json data in in StickyHeader RecyclerView from Assets Folder 【发布时间】:2021-11-10 08:18:16 【问题描述】:

我想在资产文件夹的粘性标题 recyclerview 中按日期显示我的 JSON 数据。Array 列表已接收但未显示在 recyclerview 中。我不知道我的错误在哪里。当我添加 toast 时,它显示了一个完整的 JSON 列表。但没有显示在 recyclerview 中。

MainActivity

class MainActivity : AppCompatActivity() 
    private lateinit var recyclerView: RecyclerView
    private lateinit var viewAdapter: RecyclerView.Adapter<*>
    private lateinit var viewManager: RecyclerView.LayoutManager
    var jobsArray = arrayListOf<String>()
    override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        loadJSONFromAsset()
    
    private fun loadJSONFromAsset() 
        try 
            val json: String?
            val inputStream: InputStream = assets.open("test.json")
            json = inputStream.bufferedReader().use  it.readText() 
            var jsonArray = JSONArray(json)
            for (i in 0..jsonArray.length()) 
                var jsonObject = jsonArray.getJSONObject(i)
                jobsArray.add(jsonObject.getString("data"))
            
            viewManager = LinearLayoutManager(this)
            recyclerView = findViewById<RecyclerView>(R.id.recycler_view).apply 
                viewAdapter = JobsAdapter(jobsArray)
                layoutManager = viewManager
                adapter = viewAdapter
            
            recyclerView.addItemDecoration(
                StickyHeaderItemDecoration(
                    recyclerView,
                    viewAdapter as JobsAdapter
                )
            )
         catch (ex: IOException) 
            ex.printStackTrace()
        
    

适配器类

class JobsAdapter(
    private var jobsArray: ArrayList<String>): RecyclerView.Adapter<RecyclerView.ViewHolder>(), StickyHeaderItemDecoration.StickyHeaderInterface  

    override fun isHeader(itemPosition: Int): Boolean 
    return true
    //return startTime[itemPosition].
    
    override fun bindHeaderData(header: View, headerPosition: Int) 
        ((header as ConstraintLayout).getChildAt(0) as TextView).text =
            jobsArray[headerPosition]
    
    override fun getHeaderLayout(headerPosition: Int): Int 
        return R.layout.row_header
    
    override fun getHeaderPositionForItem(itemPosition: Int): Int 
        var headerPosition = 0
        var position = itemPosition
        do 
            if (this.isHeader(position)) 
                headerPosition = position
                break
            
            position -= 1
         while (position >= 0)
        return headerPosition
    

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder 
        return if(viewType == TYPE_HEADER) 
            ViewHolderHeader(LayoutInflater.from(parent.context)
                .inflate(R.layout.row_header, parent, false))
         else 
            ViewHolder(LayoutInflater.from(parent.context)
                .inflate(R.layout.user_item, parent, false))
        
    

    override fun getItemCount() = jobsArray.size

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) 
        if(holder is ViewHolder) 
            holder.nameView.text = jobsArray[position]
         else if(holder is ViewHolderHeader) 
            holder.headerView.text = jobsArray[position]
        
    

    override fun getItemViewType(position: Int): Int 
        return if(true) 
            TYPE_HEADER
         else 
            TYPE_ITEM
        
    

    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) 
        val nameView = view.findViewById<TextView>(R.id.tv_name)
    
    class ViewHolderHeader(view: View) : RecyclerView.ViewHolder(view) 
        val headerView = view.findViewById<TextView>(R.id.headerView)
    


Json 数据(我放了一小块 json)

    
      "data": [
        
          "id": 2158,
          "title": "job schedule 13",
          "description": "job schedule 13 description\n",
          "currency": "$",
          "type": "2",
          "days": "2",
          "start_time": "2021-09-13 13:20:57",
          "end_time": "2021-09-29 13:50:00",
          "total_workers": 30,
          "hourly_rate": 12,
          "status": "Pending",
          "user": 
            "id": 165,
            "name": "Asad Employer",
            "email": "",
            "mobile_number": "+92331435343",
            "status": "Active",
            "street_address": "ichra"
          ,
]

【问题讨论】:

你试过调试吗?在你使用的 recyclerview 中的getItemCount() 上尝试一下,看看适配器是否收到任何值 还有,为什么不将这些数据解析为data class 当我调试这个时,我的应用程序在这一行崩溃了 var jsonArray = JSONArray(json),我不知道如何使用资产文件夹的数据类传递数据 错误信息是什么?并且强烈建议将您的数据解析为data class 以确保类型安全。 错误.. 原因:org.json.JSONException: Value (json response) 【参考方案1】:
    为json数据创建数据类
data class AssetJSON(
    val data: List<Data>
)

data class Data (
    val id: Long,
    val title: String,
    val description: String,
    val currency: String,
    val type: String,
    val days: String,
    val start_time: String,
    val end_time: String,
    val total_workers: Long,
    val hourly_rate: Long,
    val status: String,
    val user: User
)

data class User (
    val id: Long,
    val name: String,
    val email: String,
    val mobile_number: String,
    val status: String,
    val street_address: String
)
    Gson 安装到您的项目中
dependencies 
  implementation 'com.google.code.gson:gson:2.8.5'

    和你一样将 Json 文件解析成 Json 字符串
private fun loadJSONFromAsset(context: Context, fileName: String): String 
  return try 
        context.assets.open(fileName).bufferedReader().use  it.readText() 
     catch (e: IOException) 
        e.printStackTrace()
        null
    

    将 Json 字符串解析为数据类
val jsonString = loadJSONFromAsset(this, "test.json")
val data = Gson().fromJson(jsonString, AssetJSON::class.java)

// "data" now is your class
    将此数据传递到您的适配器,看看会抛出什么错误?

【讨论】:

先生,我在实现适配器显示许多错误后实现了这个。现在如何获取项目的位置? 先生,您的代码运行良好,但请告诉我如何相应地设置适配器? 只需将这些“数据”传递到您的适配器并使用它们到您的适配器中?有很多关于如何将值传递到 recyclerview 的教程。而recyclerview的基本概念你一定要知道

以上是关于如何从 Assets 文件夹中解析 StickyHeader RecyclerView 中的 json 数据的主要内容,如果未能解决你的问题,请参考以下文章

如何解析<IMG SRC =";值QUOT;从这个XML使用DOM

如何从 src/images 文件夹而不是 angular 2 中的 assets 文件夹加载图像

assets与static区别

如何从 nuxt.js 的 assets 文件夹中导入 css 文件

Android 如何新建assets文件夹

vue 项目中assets文件夹与static文件夹引用的区别