科特林。TypeCastException:无法将 null 强制转换为非 null 类型 kotlin.collections.MutableList

kotlin.TypeCastException: null cannot be cast to non-null type kotlin.collections.MutableList

提问人:Wini 提问时间:8/3/2020 最后编辑:Wini 更新时间:8/7/2020 访问量:3017

问:

请不要标记为重复,因为问题略有不同---> null 不能转换为非 null 类型 kotlin.collections。MutableList

场景:-

我一直在使用 Rédify 执行删除购物车。

  1. 如果至少存在一个项目,则显示在 RecyclerView 中

2.如果购物车是空的,它会崩溃并出现上述错误

这是我的适配器代码:-

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)
}

}

我试过了这个-->通过做一些改变-->

1--> var dataList: MutableList<DataCart?>

2--> var dataList: MutableList<>?=null

3--> var dataList: MutableList<>

对 Arraylist 执行 Mutablelist 后的错误日志

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)

但似乎没有任何内容在处理 null

请帮帮我

人造人 科特林 android-recyclerview 可变

评论


答:

0赞 user13043137 8/3/2020 #1

通过在购物车中设置的部件中使用 Elvis 运算符进行空检查

第一种或第二种方法似乎很好

1赞 Stanislav Bondar 8/3/2020 #2

找不到使用的理由,但您的问题是类型转换不正确。这是因为 null 无法转换为非 null 类型。您可以使用 和 remove 简化代码,并删除 和MutableList(dataList as MutableList<DataCart>)class CartAdapter(private val context: Context, private val dataList: ArrayList<DataCart?>?)var dataList: MutableList<DataCart?>private val context: Contextinit{}

评论

0赞 Wini 8/3/2020
如果我使用 List<>如果您在 tvdelete onclicklistener 下看到,我将无法获得对代码中方法的访问权限。removeAt()
0赞 Stanislav Bondar 8/3/2020
@Wini我的意思是不使用ArrayListMutableList
0赞 Stanislav Bondar 8/3/2020
@Wini发布错误日志。 可为 nullArrayList<DataCart?>?
0赞 Wini 8/3/2020
发布了我的活动,我打电话给 recycleview,请看一下
1赞 Rinat Diushenov 8/6/2020 #3

看起来可以通过更改几行来修复:

使 CartAdapter 接受可为 null 的参数,因为您的 api 请求可能会返回 null,传递它会导致 。dataListNPE

class CartAdapter(context: Context, dataList: MutableList<DataCart?>?)

由于我们的是可为空的,并且调用可能会抛出,因此我们需要使用 .如果它为 null,我们只返回 0,表示有 0 个项目。dataListdataList.sizeNPE?recyclerView

override fun getItemCount() = datalist?.size ?: 0

需要使 nullable ,因为可能会返回 .我们只是使用扩展函数转换为 mutableList,带有安全调用运算符。如果 是,则值将传递给 ,并且由于我们的适配器处理值,因此它将继续进行而不会出错val retro:List<DataCart>response.body()?.datanullretrotoMutableList()"?"retronullnullCartAdapternull

if (response.isSuccessful) {
                val retro:List<DataCart>? = response.body()?.data
                totalamount.setText(response.body()?.total.toString())
                generateDataList(retro?.toMutableList())
            }

构造函数的参数前删除函数并添加(实际上应该是)。 这里是多余的,因为您正在使用它来为冗余的重复成员变量赋值。通过将 var(should be ) 添加到构造函数参数中,它们将被分配值,并在对象构造后立即作为成员变量使用。init()CartAdaptervarvalinit()val


由于是可为空的,我们需要确定它的大小,以便进一步使用逻辑安全调用,如果它的返回 - 空dataListnulltrue

 (dataList?.isEmpty() ?: true)

或使用

`(dataList.isNullOrEmpty())` 

哪个更干净,也应该工作。


注意:就个人而言,我不建议您在每次需要更改值时都重新初始化适配器。相反,将 val 创建为成员变量,并添加一个 setter 函数来更新它,您可以在其中调用或其他通知方法。items = arrayListOf<DataCart>().notifyDatasetChanged()

评论

0赞 Wini 8/7/2020
应用程序因 Kotlin 而崩溃。TypeCastException:null 不能强制转换为非 null 类型 kotlin.collections.MutableList<com.example.xx.Cart.DataCart?> 行,指示 -->generateDataList(retro as MutableList<DataCart?>)
1赞 Rinat Diushenov 8/7/2020
你能完全删除 init{} 方法吗?这似乎有点多余,看看会发生什么?
0赞 Wini 8/7/2020
如果我删除那个 init {} ...它在 --> 处显示错误,表明它必须初始化private var dataList: MutableList<DataCart> private val context: Context
1赞 Rinat Diushenov 8/7/2020
删除这两个:private var dataList: MutableList<DataCart> private val context: Context。并在构造函数的参数前添加“var”。这样,您应该能够访问它们,而无需将它们复制为全局成员变量。我可以告诉你,你是Java的长期用户:)
1赞 Rinat Diushenov 8/7/2020
替换为 if(dataList?.isEmpty() ?: true)。非空断言 “!!” 是导致它的原因