首页 > 解决方案 > 我被卡住了,我无法使用 api Rest 将模型中的数据传递到另一个活动中

问题描述

我不知道为什么它说我“java.lang.IndexOutOfBoundsException:Index:0,Size:0”我从2小时就一直在寻找这个,我不知道为什么现在会出现这个问题,可以你帮我 ?我想将数据从 apiRest 传递到另一个带有意图和 putExtra/getExtra 的活动中(稍后我将使用 firebase,更简单和更容易的方法)。

主要活动

package com.mehdi.myapplication

class MainActivity : AppCompatActivity(), ListAdapter.OnItemClickListener {

lateinit var userAdapter: ListAdapter
var lm = LinearLayoutManager(this)
private val users: MutableList<Results> = mutableListOf()

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    initView()
    getClassApiRet()

}
override fun onItemClick(position: Int) {
    Toast.makeText(this, position.toString(), Toast.LENGTH_LONG).show()
    val intent = Intent(this, DetailPageActivity::class.java)
    intent.putExtra("email", users[position].email)
    startActivity(intent)
}

fun initView() {
    UserRecycleView.layoutManager = lm
    userAdapter = ListAdapter(this, this)
    UserRecycleView.adapter = userAdapter

}

fun getClassApiRet() {
    val retro = Instance().getRetroInstance().create(ClassApiRest::class.java)
    retro.getData().enqueue(object : Callback<ClassApi> {
        override fun onResponse(call: Call<ClassApi>, response: Response<ClassApi>) {
            val users = response.body()
            runOnUiThread {
                userAdapter.setUsers(users?.results!!)
            }
        }
        override fun onFailure(call: Call<ClassApi>, t: Throwable) {
            Log.e("Failed", t.message.toString())
        }
    })
}
}

用户信息

    class ClassApi {

    @SerializedName("results")
    @Expose
    val results: List<Results>? = null

}

class Results {

    @SerializedName("name")
    @Expose
    val name: Name? = null

    @SerializedName("email")
    @Expose
    val email: String? = null

    @SerializedName("login")
    @Expose
    val login: Login? = null

    @SerializedName("picture")
    @Expose
    val picture: Picture? = null

}

class Name {

    @SerializedName("title")
    @Expose
    val title: String? = null

    @SerializedName("first")
    @Expose
    val first: String? = null

    @SerializedName("last")
    @Expose
    val last: String? = null

}

class Login {

    @SerializedName("username")
    @Expose
    val username: String? = null

}

class Picture {

    @SerializedName("medium")
    @Expose
    val medium: String? = null

    @SerializedName("large")
    @Expose
    val large: String? = null

}

列表适配器

    class ListAdapter(val context: Context, val listener: OnItemClickListener): RecyclerView.Adapter<ListAdapter.UsersViewHolder>() {

    private val users: MutableList<Results> = mutableListOf()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListAdapter.UsersViewHolder {
        return UsersViewHolder(LayoutInflater.from(context).inflate(R.layout.row_user_list, parent, false))
    }

    override fun onBindViewHolder(holder: ListAdapter.UsersViewHolder, position: Int) {
        holder.bindModel(users[position])
    }

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

    fun setUsers(results: List<Results>) {
        users.clear()
        users.addAll(results)
        notifyDataSetChanged()
    }

    inner class UsersViewHolder(item: View) : RecyclerView.ViewHolder(item), View.OnClickListener {

        val UserImage: CircleImageView = item.findViewById(R.id.UserImage)
        val UserName: TextView = item.findViewById(R.id.UserName)
        val UserPseudo: TextView = item.findViewById(R.id.UserPseudo)

        init {
            itemView.setOnClickListener(this)
        }

        fun bindModel(b: Results) {

            UserName.text = b.name?.first
            UserPseudo.text = b.login?.username

            val url = b.picture?.medium
            Glide.with(UserImage)
                .load(url)
                .placeholder(R.drawable.ic_launcher_background)
                .error(R.drawable.ic_launcher_background)
                .fallback(R.drawable.ic_launcher_foreground)
                .into(UserImage)
        }

        override fun onClick(v: View?) {
            val position = adapterPosition
            if (position != RecyclerView.NO_POSITION) {
                listener.onItemClick(position)
            }
        }
    }
    interface OnItemClickListener {
        fun onItemClick(position: Int)
    }
}

编辑 !!!

我认为问题在于位置和接口,他无法获取数据。

ListAdapter

override fun onClick(v: View?) {
        val position = adapterPosition
        if (position != RecyclerView.NO_POSITION) {
            listener.onItemClick(position)
        }
    }
}
interface OnItemClickListener {
    fun onItemClick(position: Int)
}

主要活动

override fun onItemClick(position: Int) {
    Toast.makeText(this, users[position].email.toString(), Toast.LENGTH_LONG).show()
    val intent = Intent(this, DetailPageActivity::class.java)
    //intent.putExtra("lolipop", users[position].toString())
    startActivity(intent)
}

标签: apirestkotlinandroid-recyclerviewretrofit

解决方案


您的响应侦听器正在将用户列表传递给 ListAdapter,但它不会对 MainActivity 的users属性做任何事情,因此该列表保持为空。然后您的项目单击侦听器尝试通过该空列表中的索引访问用户。

我会users从 Activity 中删除该属性,因为它没有实际用途。在您的 ListAdapter 中,更改 OnItemClickListener 的onItemClick函数以传递实际用户而不是用户在数据中的位置。adapterPosition您可以使用适配器中的 from 获取实际用户,因为它拥有该users列表。

编辑:我建议更改您的侦听器函数签名以直接返回项目。当适配器可以直接提供它时,活动没有理由必须在集合中找到它。

// ListAdapter:

override fun onClick(v: View?) {
    listener.onItemClick(users[adapterPosition])
}

interface OnItemClickListener {
    fun onItemClick(results: Results)
}

推荐阅读