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
please dont marked as duplicate , as the question is slightly different ---> null cannot be cast to non-null type kotlin.collections.MutableList
场景:-
我一直在使用改装进行删除购物车.
i have been performing delete cart using retrofit..
- 如果至少存在一项,则会在recyclerview中显示
2.如果购物车为空,则会崩溃,并显示上述错误
2.if cart is empty ,it crashes with a above error
这是我的适配器代码:-
here is my adapter code:-
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
}}
这是我的活动:
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)
}
}
我尝试了这一点->通过做一些更改->
i tried this-->by doing some changes-->
1-> var dataList:MutableList< DataCart?>
2-> var dataList:MutableList<>?= null
3-> var dataList:MutableList<>
将Mutablelist更改为Arraylist后的错误日志
Error log after doing Mutablelist to 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$1.onResponse(AddToCart.kt:40)
at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.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)
但是似乎没有什么可以处理空
but nothing seems to be handling null
请帮助我
推荐答案
看起来只需更改几行即可解决:
Looks like it can be fixed by changing few lines:
使CartAdapter接受可为空的参数dataList
,因为您的api请求可能返回null并将其传递会导致NPE
.
Make CartAdapter accept nullable argument dataList
, since your api request may return null and passing it would cause NPE
.
class CartAdapter(context: Context, dataList: MutableList<DataCart?>?)
由于我们的dataList
可为空,并且调用dataList.size
可能会抛出NPE
,因此我们需要使用?
进行安全调用.如果它为null,则返回0,告诉recyclerView
有0个项目.
Since our dataList
is nullable and calling dataList.size
might throw NPE
we need to make safe call using ?
. And if it's null we just return 0, telling recyclerView
that there are 0 items.
override fun getItemCount() = datalist?.size ?: 0
需要使val retro:List<DataCart>
可为空,因为response.body()?.data
可能返回null
.我们只是使用扩展函数toMutableList()
和安全调用运算符"?"
将retro
转换为mutableList.如果retro
是null
,则null
值将传递给CartAdapter
,并且由于我们的适配器处理null
值,它将继续进行而不会出错
Need to make val retro:List<DataCart>
nullable, because response.body()?.data
may return null
. We just convert retro
to mutableList using extension function toMutableList()
, with safe call operator "?"
. If retro
is null
then null
value will be passed to CartAdapter
, and since our adapter handles null
value it will proceed without errors
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(应该为val
),它们将被分配值,并在对象构造后立即用作成员变量.
Remove init()
function from CartAdapter
and add var
(actually should be val
) before arguments in constructor. init()
is redundant here because u r using it to assign values to redundant, duplicate member variables. By adding var(should be val
) to constructor arguments they will be assigned values and be available as member variables, right after object construction.
由于dataList
是可为空的,因此我们需要确定其大小以用于进一步的逻辑安全调用,以及是否null
返回true
-空
Since dataList
is nullable, and we need to determine its size for further logic safe call needs to be used, and if its null
return true
- empty
(dataList?.isEmpty() ?: true)
或使用
`(dataList.isNullOrEmpty())`
这更干净,也应该可以工作.
which is cleaner, and should work too.
注意:就个人而言,我不建议您每次需要更改值时都重新初始化Adapter.而是将val items = arrayListOf<DataCart>().
创建为成员变量,并添加一个setter函数以对其进行更新,在其中可以调用notifyDatasetChanged()
或其他通知方法.
NOTE: Personally, i would'nt suggest you to retinitialize Adapter everytime you need to change values. Instead create val items = arrayListOf<DataCart>().
as a member variable and add a setter function for updating it, inside of which you would call notifyDatasetChanged()
or other notify methods.
这篇关于kotlin.TypeCastException:无法将null强制转换为非null类型kotlin.collections.MutableList的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!