kotlin.TypeCastException: null 不能转换为非 null 类型 kotlin.collections.MutableList
kotlin.TypeCastException: null cannot be cast to non-null type kotlin.collections.MutableList
请不要标记为重复,因为问题略有不同 ---> null 不能转换为非 null 类型 kotlin.collections.MutableList
场景:-
我一直在使用改造执行删除购物车..
- 如果至少有一项,它会显示在 recyclerview 中
2.if 购物车是空的,它因上述错误而崩溃
这是我的适配器代码:-
class CartAdapter(context: Context, dataList: MutableList<DataCart?>) :
RecyclerSwipeAdapter<CartAdapter.CustomViewHolder>() { //added RecyclerSwipeAdapter and override
private var dataList: MutableList<DataCart>
private val context: Context
lateinit var dialog:ProgressDialog
var progressDialog: ProgressDialog? = null
inner class CustomViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val mView: View
val swipelayout:SwipeLayout
val productiamge: ImageView
val productname: TextView
val productcategory: TextView
val productprice: TextView
val quantity:TextView
val tvDelete:TextView
init {
mView = itemView
productiamge= mView.findViewById(R.id.imagecart)
productname= mView.findViewById(R.id.imagenamecart)
productcategory= mView.findViewById(R.id.imagecategory)
productprice =mView.findViewById(R.id.price)
quantity=mView.findViewById(R.id.quantity)
swipelayout=mView.findViewById(R.id.swipe)
tvDelete=mView.findViewById(R.id.tvDelete)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val view: View = layoutInflater.inflate(R.layout.addtocart_item, parent, false)
return CustomViewHolder(view)
}
override fun getSwipeLayoutResourceId(position: Int): Int {
return R.id.swipe;
}
override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
val progressDialog :ProgressDialog= ProgressDialog(context);
holder.productname.text = dataList.get(position).product.name ?: null
holder.productcategory.text = "(" +dataList.get(position).product.product_category +")"
holder.productprice.text = dataList.get(position).product.cost.toString()
Glide.with(context).load(dataList.get(position).product.product_images)
.into(holder.productiamge)
holder.quantity.text=dataList.get(position).quantity.toString()
holder.swipelayout.setShowMode(SwipeLayout.ShowMode.PullOut)
Log.e("checkidd",dataList.get(position).product.id.toString())
// Drag From Right
// Drag From Right
holder.swipelayout.addDrag(
SwipeLayout.DragEdge.Right,
holder.swipelayout.findViewById(R.id.bottom_wrapper)
)
val id =dataList.get(position).product?.id
holder.swipelayout.addSwipeListener(object : SwipeListener {
override fun onClose(layout: SwipeLayout) { }
override fun onUpdate(layout: SwipeLayout, leftOffset: Int, topOffset: Int) {
//you are swiping.
}
override fun onStartOpen(layout: SwipeLayout) {}
override fun onOpen(layout: SwipeLayout) {
}
override fun onStartClose(layout: SwipeLayout) {}
override fun onHandRelease(
layout: SwipeLayout,
xvel: Float,
yvel: Float
) {
}
})
holder.swipelayout.getSurfaceView()
.setOnClickListener(View.OnClickListener {
})
holder.tvDelete.setOnClickListener(View.OnClickListener {
view ->
val token :String = SharedPrefManager.getInstance(context).user.access_token.toString()
RetrofitClient.instancecart.deletecart(token,id!!)
.enqueue(object : Callback<DeleteResponse> {
override fun onFailure(call: Call<DeleteResponse>, t: Throwable) {
}
override fun onResponse(
call: Call<DeleteResponse>,
response: Response<DeleteResponse>
) {
var res = response
if (res.body()?.status==200) {
Toast.makeText(
context,
res.body()?.message,
Toast.LENGTH_LONG
).show()
progress()
mItemManger.removeShownLayouts(holder.swipelayout)
notifyItemChanged(position)
notifyItemRemoved(position)
dataList?.removeAt(position)
notifyItemRangeChanged(position, dataList?.size!!)
mItemManger.closeAllItems()
progressDialog.show()
}
else{
try {
val jObjError =
JSONObject(response.errorBody()!!.string())
Toast.makeText(
context,
jObjError.getString("message")+jObjError.getString("user_msg"),
Toast.LENGTH_LONG
).show()
} catch (e: Exception) {
Toast.makeText(context, e.message, Toast.LENGTH_LONG).show()
Log.e("errorrr",e.message)
}
}
}
})
mItemManger.bindView(holder.itemView, position)
})
}
override fun getItemCount(): Int {
return dataList.size
}
fun progress()
{
progressDialog?.dismiss()
val intent =
Intent(context.applicationContext, AddToCart::class.java)
intent.flags =
Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_MULTIPLE_TASK
context.applicationContext.startActivity(intent)
}
init {
this.context = context
this.dataList = dataList
}}
这是我的 activity:
class AddToCart:AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.add_to_cart)
val totalamount:TextView=findViewById(R.id.totalamount)
val token: String =
SharedPrefManager.getInstance(
applicationContext
).user.access_token.toString()
RetrofitClient.instancecart.listcart(token).enqueue( object :
Callback<CartResponse> {
override fun onFailure(call: Call<CartResponse>, t: Throwable) {
Toast.makeText(applicationContext,"falied", Toast.LENGTH_LONG).show()
}
override fun onResponse(
call: Call<CartResponse>,
response: Response<CartResponse>
) {
val res=response
if (response.isSuccessful) {
val retro:List<DataCart> = response.body()!!.data
totalamount.setText(response.body()?.total.toString())
generateDataList(retro as MutableList<DataCart?>)
}
}
})
}
fun generateDataList( dataList:MutableList<DataCart?>) {
val recyclerView=findViewById<RecyclerView>(R.id.addtocartrecyleview) as? RecyclerView
val linear:LinearLayoutManager=
LinearLayoutManager(applicationContext,LinearLayoutManager.VERTICAL, false)
recyclerView?.layoutManager=linear
val adapter = CartAdapter(this@AddToCart,dataList)
recyclerView?.adapter=adapter
recyclerView?.addItemDecoration
(DividerItemDecorator(resources.getDrawable(R.drawable.divider)))
recyclerView?.setHasFixedSize(true)
adapter.notifyDataSetChanged()
if (dataList.isEmpty()) {
recyclerView?.setVisibility(View.GONE)
textviewempty.setVisibility(View.VISIBLE)
} else {
recyclerView?.setVisibility(View.VISIBLE)
textviewempty.setVisibility(View.GONE)
}
recyclerView?.addOnScrollListener(object :
RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
Log.e("RecyclerView", "onScrollStateChanged")
}
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
}
})
}
override fun onBackPressed() {
super.onBackPressed()
val intent = Intent(this, HomeActivity::class.java)
startActivityForResult(intent, 2)
}
}
我试过了-->通过做一些改变-->
1--> var dataList: MutableList
2--> var dataList: MutableList<>?=null
3--> var dataList: MutableList<>
从 Mutablelist 到 Arraylist 后的错误日志
kotlin.TypeCastException: null cannot be cast to non-null type java.util.ArrayList<com.example.store.Cart.DataCart>
at com.example.store.Cart.AddToCart$onCreate.onResponse(AddToCart.kt:40)
at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall.run(ExecutorCallAdapterFactory.java:70)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:224)
at android.app.ActivityThread.main(ActivityThread.java:7147)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:536)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:876)
但似乎没有任何东西在处理 null
请帮帮我
购物车设置部分使用Elvis运算符进行空校验
第一种或者第二种方法好像不错
找不到使用 MutableList
的理由,但您的问题是类型转换不正确 (dataList as MutableList<DataCart>)
。这是因为 null 无法转换为 non-null 类型。您可以使用 class CartAdapter(private val context: Context, private val dataList: ArrayList<DataCart?>?)
简化代码并删除 var dataList: MutableList<DataCart?>
、private val context: Context
和 init{}
看起来可以通过更改几行来解决:
使 CartAdapter 接受可为空的参数 dataList
,因为您的 api 请求可能 return 为空并且传递它会导致 NPE
.
class CartAdapter(context: Context, dataList: MutableList<DataCart?>?)
由于我们的 dataList
可以为空并且调用 dataList.size
可能会抛出 NPE
我们需要使用 ?
进行安全调用。如果它为空,我们只是 return 0,告诉 recyclerView
有 0 个项目。
override fun getItemCount() = datalist?.size ?: 0
需要使 val retro:List<DataCart>
可为空,因为 response.body()?.data
可能 return null
。我们只是使用扩展函数 toMutableList()
和安全调用运算符 "?"
将 retro
转换为 mutableList。如果 retro
是 null
,那么 null
值将被传递给 CartAdapter
,并且由于我们的适配器处理 null
值,它将继续而没有错误
if (response.isSuccessful) {
val retro:List<DataCart>? = response.body()?.data
totalamount.setText(response.body()?.total.toString())
generateDataList(retro?.toMutableList())
}
从CartAdapter
中删除init()
函数并在构造函数的参数前添加var
(实际上应该是val
)。 init()
在这里是多余的,因为你用它来给多余的、重复的成员变量赋值。通过将 var(should be val
) 添加到构造函数参数中,它们将被赋值并在对象构造之后立即作为成员变量使用。
由于 dataList
可以为空,我们需要确定它的大小以便进一步逻辑安全调用需要使用,如果它的 null
return true
-空
(dataList?.isEmpty() ?: true)
或使用
`(dataList.isNullOrEmpty())`
哪个更干净,应该也能用。
注意: 就个人而言,我不建议您每次需要更改值时都重新初始化 Adapter。而是创建 val items = arrayListOf<DataCart>().
作为成员变量并添加一个 setter 函数来更新它,在其中您可以调用 notifyDatasetChanged()
或其他通知方法。
请不要标记为重复,因为问题略有不同 ---> null 不能转换为非 null 类型 kotlin.collections.MutableList
场景:-
我一直在使用改造执行删除购物车..
- 如果至少有一项,它会显示在 recyclerview 中
2.if 购物车是空的,它因上述错误而崩溃
这是我的适配器代码:-
class CartAdapter(context: Context, dataList: MutableList<DataCart?>) :
RecyclerSwipeAdapter<CartAdapter.CustomViewHolder>() { //added RecyclerSwipeAdapter and override
private var dataList: MutableList<DataCart>
private val context: Context
lateinit var dialog:ProgressDialog
var progressDialog: ProgressDialog? = null
inner class CustomViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val mView: View
val swipelayout:SwipeLayout
val productiamge: ImageView
val productname: TextView
val productcategory: TextView
val productprice: TextView
val quantity:TextView
val tvDelete:TextView
init {
mView = itemView
productiamge= mView.findViewById(R.id.imagecart)
productname= mView.findViewById(R.id.imagenamecart)
productcategory= mView.findViewById(R.id.imagecategory)
productprice =mView.findViewById(R.id.price)
quantity=mView.findViewById(R.id.quantity)
swipelayout=mView.findViewById(R.id.swipe)
tvDelete=mView.findViewById(R.id.tvDelete)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val view: View = layoutInflater.inflate(R.layout.addtocart_item, parent, false)
return CustomViewHolder(view)
}
override fun getSwipeLayoutResourceId(position: Int): Int {
return R.id.swipe;
}
override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
val progressDialog :ProgressDialog= ProgressDialog(context);
holder.productname.text = dataList.get(position).product.name ?: null
holder.productcategory.text = "(" +dataList.get(position).product.product_category +")"
holder.productprice.text = dataList.get(position).product.cost.toString()
Glide.with(context).load(dataList.get(position).product.product_images)
.into(holder.productiamge)
holder.quantity.text=dataList.get(position).quantity.toString()
holder.swipelayout.setShowMode(SwipeLayout.ShowMode.PullOut)
Log.e("checkidd",dataList.get(position).product.id.toString())
// Drag From Right
// Drag From Right
holder.swipelayout.addDrag(
SwipeLayout.DragEdge.Right,
holder.swipelayout.findViewById(R.id.bottom_wrapper)
)
val id =dataList.get(position).product?.id
holder.swipelayout.addSwipeListener(object : SwipeListener {
override fun onClose(layout: SwipeLayout) { }
override fun onUpdate(layout: SwipeLayout, leftOffset: Int, topOffset: Int) {
//you are swiping.
}
override fun onStartOpen(layout: SwipeLayout) {}
override fun onOpen(layout: SwipeLayout) {
}
override fun onStartClose(layout: SwipeLayout) {}
override fun onHandRelease(
layout: SwipeLayout,
xvel: Float,
yvel: Float
) {
}
})
holder.swipelayout.getSurfaceView()
.setOnClickListener(View.OnClickListener {
})
holder.tvDelete.setOnClickListener(View.OnClickListener {
view ->
val token :String = SharedPrefManager.getInstance(context).user.access_token.toString()
RetrofitClient.instancecart.deletecart(token,id!!)
.enqueue(object : Callback<DeleteResponse> {
override fun onFailure(call: Call<DeleteResponse>, t: Throwable) {
}
override fun onResponse(
call: Call<DeleteResponse>,
response: Response<DeleteResponse>
) {
var res = response
if (res.body()?.status==200) {
Toast.makeText(
context,
res.body()?.message,
Toast.LENGTH_LONG
).show()
progress()
mItemManger.removeShownLayouts(holder.swipelayout)
notifyItemChanged(position)
notifyItemRemoved(position)
dataList?.removeAt(position)
notifyItemRangeChanged(position, dataList?.size!!)
mItemManger.closeAllItems()
progressDialog.show()
}
else{
try {
val jObjError =
JSONObject(response.errorBody()!!.string())
Toast.makeText(
context,
jObjError.getString("message")+jObjError.getString("user_msg"),
Toast.LENGTH_LONG
).show()
} catch (e: Exception) {
Toast.makeText(context, e.message, Toast.LENGTH_LONG).show()
Log.e("errorrr",e.message)
}
}
}
})
mItemManger.bindView(holder.itemView, position)
})
}
override fun getItemCount(): Int {
return dataList.size
}
fun progress()
{
progressDialog?.dismiss()
val intent =
Intent(context.applicationContext, AddToCart::class.java)
intent.flags =
Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_MULTIPLE_TASK
context.applicationContext.startActivity(intent)
}
init {
this.context = context
this.dataList = dataList
}}
这是我的 activity:
class AddToCart:AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.add_to_cart)
val totalamount:TextView=findViewById(R.id.totalamount)
val token: String =
SharedPrefManager.getInstance(
applicationContext
).user.access_token.toString()
RetrofitClient.instancecart.listcart(token).enqueue( object :
Callback<CartResponse> {
override fun onFailure(call: Call<CartResponse>, t: Throwable) {
Toast.makeText(applicationContext,"falied", Toast.LENGTH_LONG).show()
}
override fun onResponse(
call: Call<CartResponse>,
response: Response<CartResponse>
) {
val res=response
if (response.isSuccessful) {
val retro:List<DataCart> = response.body()!!.data
totalamount.setText(response.body()?.total.toString())
generateDataList(retro as MutableList<DataCart?>)
}
}
})
}
fun generateDataList( dataList:MutableList<DataCart?>) {
val recyclerView=findViewById<RecyclerView>(R.id.addtocartrecyleview) as? RecyclerView
val linear:LinearLayoutManager=
LinearLayoutManager(applicationContext,LinearLayoutManager.VERTICAL, false)
recyclerView?.layoutManager=linear
val adapter = CartAdapter(this@AddToCart,dataList)
recyclerView?.adapter=adapter
recyclerView?.addItemDecoration
(DividerItemDecorator(resources.getDrawable(R.drawable.divider)))
recyclerView?.setHasFixedSize(true)
adapter.notifyDataSetChanged()
if (dataList.isEmpty()) {
recyclerView?.setVisibility(View.GONE)
textviewempty.setVisibility(View.VISIBLE)
} else {
recyclerView?.setVisibility(View.VISIBLE)
textviewempty.setVisibility(View.GONE)
}
recyclerView?.addOnScrollListener(object :
RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
Log.e("RecyclerView", "onScrollStateChanged")
}
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
}
})
}
override fun onBackPressed() {
super.onBackPressed()
val intent = Intent(this, HomeActivity::class.java)
startActivityForResult(intent, 2)
}
}
我试过了-->通过做一些改变-->
1--> var dataList: MutableList
2--> var dataList: MutableList<>?=null
3--> var dataList: MutableList<>
从 Mutablelist 到 Arraylist 后的错误日志
kotlin.TypeCastException: null cannot be cast to non-null type java.util.ArrayList<com.example.store.Cart.DataCart>
at com.example.store.Cart.AddToCart$onCreate.onResponse(AddToCart.kt:40)
at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall.run(ExecutorCallAdapterFactory.java:70)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:224)
at android.app.ActivityThread.main(ActivityThread.java:7147)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:536)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:876)
但似乎没有任何东西在处理 null
请帮帮我
购物车设置部分使用Elvis运算符进行空校验
第一种或者第二种方法好像不错
找不到使用 MutableList
的理由,但您的问题是类型转换不正确 (dataList as MutableList<DataCart>)
。这是因为 null 无法转换为 non-null 类型。您可以使用 class CartAdapter(private val context: Context, private val dataList: ArrayList<DataCart?>?)
简化代码并删除 var dataList: MutableList<DataCart?>
、private val context: Context
和 init{}
看起来可以通过更改几行来解决:
使 CartAdapter 接受可为空的参数 dataList
,因为您的 api 请求可能 return 为空并且传递它会导致 NPE
.
class CartAdapter(context: Context, dataList: MutableList<DataCart?>?)
由于我们的 dataList
可以为空并且调用 dataList.size
可能会抛出 NPE
我们需要使用 ?
进行安全调用。如果它为空,我们只是 return 0,告诉 recyclerView
有 0 个项目。
override fun getItemCount() = datalist?.size ?: 0
需要使 val retro:List<DataCart>
可为空,因为 response.body()?.data
可能 return null
。我们只是使用扩展函数 toMutableList()
和安全调用运算符 "?"
将 retro
转换为 mutableList。如果 retro
是 null
,那么 null
值将被传递给 CartAdapter
,并且由于我们的适配器处理 null
值,它将继续而没有错误
if (response.isSuccessful) {
val retro:List<DataCart>? = response.body()?.data
totalamount.setText(response.body()?.total.toString())
generateDataList(retro?.toMutableList())
}
从CartAdapter
中删除init()
函数并在构造函数的参数前添加var
(实际上应该是val
)。 init()
在这里是多余的,因为你用它来给多余的、重复的成员变量赋值。通过将 var(should be val
) 添加到构造函数参数中,它们将被赋值并在对象构造之后立即作为成员变量使用。
由于 dataList
可以为空,我们需要确定它的大小以便进一步逻辑安全调用需要使用,如果它的 null
return true
-空
(dataList?.isEmpty() ?: true)
或使用
`(dataList.isNullOrEmpty())`
哪个更干净,应该也能用。
注意: 就个人而言,我不建议您每次需要更改值时都重新初始化 Adapter。而是创建 val items = arrayListOf<DataCart>().
作为成员变量并添加一个 setter 函数来更新它,在其中您可以调用 notifyDatasetChanged()
或其他通知方法。