【问题标题】:How to parse json data in in StickyHeader RecyclerView from Assets Folder如何从 Assets 文件夹中解析 StickyHeader RecyclerView 中的 json 数据
【发布时间】:2023-03-22 06:30:01
【问题描述】:

我想在资产文件夹的粘性标题 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)

标签: java android json xml kotlin


【解决方案1】:
  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
)
  1. Gson 安装到您的项目中
dependencies {
  implementation 'com.google.code.gson:gson:2.8.5'
}
  1. 和你一样将 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
    }
}
  1. 将 Json 字符串解析为数据类
val jsonString = loadJSONFromAsset(this, "test.json")
val data = Gson().fromJson(jsonString, AssetJSON::class.java)

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

【讨论】:

  • 先生,我在实现适配器显示许多错误后实现了这个。现在如何获取项目的位置?
  • 先生,您的代码运行良好,但请告诉我如何相应地设置适配器?
  • 只需将这些“数据”传递到您的适配器并使用它们到您的适配器中?有很多关于如何将值传递到 recyclerview 的教程。而recyclerview的基本概念你一定要知道
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-20
  • 1970-01-01
  • 2022-08-23
  • 2012-04-07
  • 2019-06-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多