kotlin .TypeCastException: null не может быть преобразован в ненулевой тип kotlin .collections.MutableList - PullRequest
0 голосов
/ 03 августа 2020

, пожалуйста, не помечайте как дубликат, так как вопрос немного отличается ---> null не может быть приведен к ненулевому типу kotlin .collections. MutableList

Scener ios: -

Я выполнял удаление корзины с помощью модернизации ..

  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

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$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

Пожалуйста, помогите мне

Ответы [ 3 ]

1 голос
/ 03 августа 2020

Не могу найти причину использовать MutableList, но ваша проблема - неправильное приведение типа (dataList as MutableList<DataCart>). Это потому, что null не может быть приведен к ненулевому типу. Вы можете упростить код, используя class CartAdapter(private val context: Context, private val dataList: ArrayList<DataCart?>?), и удалить var dataList: MutableList<DataCart?>, private val context: Context и init{}

1 голос
/ 06 августа 2020
• 1000 *

Поскольку наш dataList допускает значение NULL и вызов dataList.size может выдать NPE, нам нужно сделать безопасный вызов, используя ?. И если он равен нулю, мы просто возвращаем 0, сообщая recyclerView, что элементов 0.

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

Необходимо сделать val retro:List<DataCart> обнуляемым, потому что response.body()?.data может вернуть null. Мы просто конвертируем retro в mutableList с помощью функции расширения toMutableList() с оператором безопасного вызова "?". Если retro равно null, то значение null будет передано в CartAdapter, и, поскольку наш адаптер обрабатывает значение null, он будет работать без ошибок

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

Удалите функцию init() из CartAdapter и добавьте var (на самом деле должно быть val) перед аргументами в конструкторе. init() здесь избыточно, потому что ur использует его для присвоения значений избыточным, повторяющимся переменным-членам. При добавлении var (должно быть val) к аргументам конструктора им будут присвоены значения и они будут доступны как переменные-члены сразу после создания объекта.

Поскольку dataList допускает значение NULL, и нам нужно определить его размер для дальнейшего logi, необходимо использовать c безопасный вызов, а если его null return true - пусто

 (dataList?.isEmpty() ?: true)

или используйте

`(dataList.isNullOrEmpty())` 

, который чище и тоже должен работать.

ПРИМЕЧАНИЕ: Лично я бы не предлагал вам повторно инициализировать адаптер каждый раз, когда вам нужно изменить значения. Вместо этого создайте val items = arrayListOf<DataCart>(). как переменную-член и добавьте функцию установки для ее обновления, внутри которой вы должны вызвать notifyDatasetChanged() или другие методы уведомления.

0 голосов
/ 03 августа 2020

Проверка нуля с помощью оператора Элвиса в части, которая устанавливается в корзине покупок

Первый или второй метод кажутся хорошими

...