请不要将其标记为重复,因为问题略有不同--->不能将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..
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
发布评论