有人可以看看我的项目并告诉我为什么它在 运行 之前出错吗?
Could someone take a look at my project and tell me why it errors before running?
您好,感谢您提前阅读,
我已经构建了一个小项目来测试适配器以使用自定义 xml 模板填充主 activity 视图 [此模板包含一些字段,这些字段由项目内的一些简单测试数据和图像填充]
该构建很好 afaik,我已尽我所能调试它以不产生任何错误,而且我在调试中遵循构建时实际上找不到错误,所以这可能是我对 kotlin、android studio 和也许以后的开发方式会改变。
我最好的猜测是在跟随它几次(更多 ha)次之后,在这个阶段它似乎在构建的 android 部分与任何准备和适配器代码中出错,所以它可能是我没有的一些设置调用也许...
同样重要的是:我看到它在调试期间拉入了 recyclerView(在我使用导入的 xml 布局进行任何自定义之前),然后视觉效果消失了,但我确实看到所有代码都由我创建的函数填充在 MainActivity 中,适配器似乎确实 return 向 MainActivity 构造了各自的数据。
我附上了压缩的项目,因为我找不到可识别的错误代码或 post 运行时退出代码 [这并不是说没有,我是 IDE 的新手 :( ]
我的目标是 Android 7.0 600*1024 mdpi 在 7"(左手翻转)纵向 x86 模拟器上使用 API 24
我正在使用 Android Studio 2021.1.1 补丁 3 如果知道这也很重要的话
再次感谢任何能看一眼它来帮助我的人,我真的卡住了,现在已经这样了几天,再次考虑完全重做:/
:)
我将 link 附在下面的压缩文件中 [由于在此处提供的调试中没有错误]
[编辑:Cripes 我忘了说我也在使用 CircleImageViewer,不确定这是否会导致问题,但它似乎不是]
[最终编辑:如下所示,Tyler V 回答了这个问题,他比我提出的问题更了解我的问题 - 请参阅下面的完整解决方案/代码重构,它们可以正常工作 - 谢谢再次致泰勒五世]
我看了你的应用程序,它抛出的错误 (look in the Logcat tab!) 是这样的
Process: com.example.kayakthing, PID: 4289
java.lang.IndexOutOfBoundsException: Index: 5, Size: 5
at java.util.ArrayList.get(ArrayList.java:411)
at com.example.kayakthing.HiresAdapter.onBindViewHolder(HiresAdapter.kt:34)
at com.example.kayakthing.HiresAdapter.onBindViewHolder(HiresAdapter.kt:11)
问题
它抛出的原因是因为您向适配器提供了不同长度的数组。查看下面的适配器代码 - 在您当前的代码中,nameList
和 clientDetailsList
的长度均为 7,但 hireImageList
的长度为 5。由于您定义了 getItemCount
基于 nameList
的长度 - 当尝试显示超过 hireImageList
大小末尾的位置值时,适配器会崩溃。
override fun onBindViewHolder(holder: HiresViewHolder, position: Int) {
holder.tvClientName.text = nameList[position]
holder.tvClientDetails.text = clientDetailsList[position]
holder.imageView.setImageResource(hireImageList[position])
}
override fun getItemCount(): Int {
return nameList.size
}
解决方案
我推荐你1)学会阅读Logcat选项卡来查找错误,以及2)定义一个数据class来保存你在适配器中需要的三个项目,这样你就可以通过在该数据的单个列表中 class 而不是三个列表。这样就无法传入长度为 mis-matched 的列表。
例如,使用这样的东西并让适配器采用单个 List<HiresAdapter.Data>
而不是三个列表。
class HiresAdapter(
private var adapterData: ArrayList<Data>,
private var context: Context) : RecyclerView.Adapter<HiresAdapter.HiresViewHolder>() {
// Define a data class in the adapter to hold the data
// needed for each row
data class Data(val name: String, val details: String, val image: Int)
class HiresViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var tvClientName : TextView = itemView.findViewById(R.id.tvClientName)
var tvClientDetails : TextView = itemView.findViewById(R.id.tvClientDetail)
var imageView : CircleImageView = itemView.findViewById(R.id.hireImageView)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) : HiresViewHolder {
this.context = parent.context
val view : View = LayoutInflater.from(this.context).inflate(R.layout.rv_card_design,parent, false)
return HiresViewHolder(view)
}
override fun onBindViewHolder(holder: HiresViewHolder, position: Int) {
holder.tvClientName.text = adapterData[position].name
holder.tvClientDetails.text = adapterData[position].details
holder.imageView.setImageResource(adapterData[position].image)
}
override fun getItemCount(): Int {
return adapterData.size
}
}
并像这样填充它
val adapterData = ArrayList<HiresAdapter.Data>()
adapterData.add(HiresAdapter.Data("Geoff", "Geoff", R.drawable.solo))
adapterData.add(HiresAdapter.Data("Frogme", "Frogme", R.drawable.tandem))
adapterData.add(HiresAdapter.Data("Jenny", "Jenny", R.drawable.quattro))
adapterData.add(HiresAdapter.Data("Benny", "Benny", R.drawable.sup))
adapterData.add(HiresAdapter.Data("Sylvia", "Sylvia", R.drawable.croc))
adapter = HiresAdapter(adapterData, this@MainActivity)
您好,感谢您提前阅读, 我已经构建了一个小项目来测试适配器以使用自定义 xml 模板填充主 activity 视图 [此模板包含一些字段,这些字段由项目内的一些简单测试数据和图像填充] 该构建很好 afaik,我已尽我所能调试它以不产生任何错误,而且我在调试中遵循构建时实际上找不到错误,所以这可能是我对 kotlin、android studio 和也许以后的开发方式会改变。 我最好的猜测是在跟随它几次(更多 ha)次之后,在这个阶段它似乎在构建的 android 部分与任何准备和适配器代码中出错,所以它可能是我没有的一些设置调用也许... 同样重要的是:我看到它在调试期间拉入了 recyclerView(在我使用导入的 xml 布局进行任何自定义之前),然后视觉效果消失了,但我确实看到所有代码都由我创建的函数填充在 MainActivity 中,适配器似乎确实 return 向 MainActivity 构造了各自的数据。 我附上了压缩的项目,因为我找不到可识别的错误代码或 post 运行时退出代码 [这并不是说没有,我是 IDE 的新手 :( ] 我的目标是 Android 7.0 600*1024 mdpi 在 7"(左手翻转)纵向 x86 模拟器上使用 API 24
我正在使用 Android Studio 2021.1.1 补丁 3 如果知道这也很重要的话
再次感谢任何能看一眼它来帮助我的人,我真的卡住了,现在已经这样了几天,再次考虑完全重做:/ :) 我将 link 附在下面的压缩文件中 [由于在此处提供的调试中没有错误]
[编辑:Cripes 我忘了说我也在使用 CircleImageViewer,不确定这是否会导致问题,但它似乎不是]
[最终编辑:如下所示,Tyler V 回答了这个问题,他比我提出的问题更了解我的问题 - 请参阅下面的完整解决方案/代码重构,它们可以正常工作 - 谢谢再次致泰勒五世]
我看了你的应用程序,它抛出的错误 (look in the Logcat tab!) 是这样的
Process: com.example.kayakthing, PID: 4289
java.lang.IndexOutOfBoundsException: Index: 5, Size: 5
at java.util.ArrayList.get(ArrayList.java:411)
at com.example.kayakthing.HiresAdapter.onBindViewHolder(HiresAdapter.kt:34)
at com.example.kayakthing.HiresAdapter.onBindViewHolder(HiresAdapter.kt:11)
问题
它抛出的原因是因为您向适配器提供了不同长度的数组。查看下面的适配器代码 - 在您当前的代码中,nameList
和 clientDetailsList
的长度均为 7,但 hireImageList
的长度为 5。由于您定义了 getItemCount
基于 nameList
的长度 - 当尝试显示超过 hireImageList
大小末尾的位置值时,适配器会崩溃。
override fun onBindViewHolder(holder: HiresViewHolder, position: Int) {
holder.tvClientName.text = nameList[position]
holder.tvClientDetails.text = clientDetailsList[position]
holder.imageView.setImageResource(hireImageList[position])
}
override fun getItemCount(): Int {
return nameList.size
}
解决方案
我推荐你1)学会阅读Logcat选项卡来查找错误,以及2)定义一个数据class来保存你在适配器中需要的三个项目,这样你就可以通过在该数据的单个列表中 class 而不是三个列表。这样就无法传入长度为 mis-matched 的列表。
例如,使用这样的东西并让适配器采用单个 List<HiresAdapter.Data>
而不是三个列表。
class HiresAdapter(
private var adapterData: ArrayList<Data>,
private var context: Context) : RecyclerView.Adapter<HiresAdapter.HiresViewHolder>() {
// Define a data class in the adapter to hold the data
// needed for each row
data class Data(val name: String, val details: String, val image: Int)
class HiresViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var tvClientName : TextView = itemView.findViewById(R.id.tvClientName)
var tvClientDetails : TextView = itemView.findViewById(R.id.tvClientDetail)
var imageView : CircleImageView = itemView.findViewById(R.id.hireImageView)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) : HiresViewHolder {
this.context = parent.context
val view : View = LayoutInflater.from(this.context).inflate(R.layout.rv_card_design,parent, false)
return HiresViewHolder(view)
}
override fun onBindViewHolder(holder: HiresViewHolder, position: Int) {
holder.tvClientName.text = adapterData[position].name
holder.tvClientDetails.text = adapterData[position].details
holder.imageView.setImageResource(adapterData[position].image)
}
override fun getItemCount(): Int {
return adapterData.size
}
}
并像这样填充它
val adapterData = ArrayList<HiresAdapter.Data>()
adapterData.add(HiresAdapter.Data("Geoff", "Geoff", R.drawable.solo))
adapterData.add(HiresAdapter.Data("Frogme", "Frogme", R.drawable.tandem))
adapterData.add(HiresAdapter.Data("Jenny", "Jenny", R.drawable.quattro))
adapterData.add(HiresAdapter.Data("Benny", "Benny", R.drawable.sup))
adapterData.add(HiresAdapter.Data("Sylvia", "Sylvia", R.drawable.croc))
adapter = HiresAdapter(adapterData, this@MainActivity)