Значение счетчика с использованием модернизации и viewmodel

#android #kotlin #spinner #viewmodel #android-spinner

#Android #kotlin #счетчик #viewmodel #android-счетчик

Вопрос:

Я пытаюсь реализовать корзину редактирования в своем проекте. Для этого я использовал счетчик. Я опубликовал два метода: один с использованием ViewModel и один без. Когда я не использую ViewModel, он работает нормально. Проблема заключается в использовании ViewModel.

Без использования ViewModel он отправляет правильное значение в вызове, правильно устанавливая значение в счетчике при повторном посещении корзины, однако при использовании ViewModel, если я устанавливаю счетчик как 3, он показывает успех, но при повторном просмотре я вижу 8 в счетчике и даже в запросе REST, который я делаюиспользуя Postman, я вижу 8 в ответе.

Адаптер:

 var country = arrayOf(1, 2, 3, 4, 5, 6, 7, 8)
/***  */
val aa: ArrayAdapter <*> =
        ArrayAdapter<Any?>(context, android.R.layout.simple_spinner_item, country)
aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
holder.spin.setAdapter(aa)
holder.spin.setSelection(dataList?.get(position)?.quantity!! - 1, false)
holder.spin.setOnItemSelectedListener(object : OnItemSelectedListener {
    override fun onItemSelected(
            parent: AdapterView<*>,
            view: View,
            position1: Int,
            id: Long
    ) {
        progressDialog.show()
        val id = dataList?.get(position)!!.product.id
        itemClick?.EditItem(position1, id!!.toInt())
    }
    override fun onNothingSelected(parent: AdapterView<*>?) {
        // todo for nothing selected
    }
})
  

Интерфейс:

 interface OnItemClick {
    fun DeleteItem(position: Int, id:Int)
    fun EditItem(position: Int,id: Int)
}
  

Активность:

 var country = arrayOf(1, 2, 3, 4, 5, 6, 7, 8)

/* */
override fun EditItem(position: Int, id: Int) {
    val token: String = SharedPrefManager.getInstance(applicationContext).user.access_token.toString()
    RetrofitClient.instance.editCart(token, id, arrayOf(country[position]))
            .enqueue(object : Callback<DeleteResponse> {
                override fun onFailure(call: Call<DeleteResponse>, t: Throwable) {
                    Log.d("res", ""   t)
                }

                override fun onResponse(call: Call<DeleteResponse>, response: Response<DeleteResponse>) {
                    progressDialog?.dismiss()
                    finish()
                    var res = response
                    if (res.isSuccessful) {
                        Toast.makeText(applicationContext, res.body()?.user_msg, Toast.LENGTH_LONG).show()
                        progressDialog?.dismiss()
                        val intent = Intent(applicationContext, AddToCart::class.java)
                        intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_MULTIPLE_TASK
                        applicationContext.startActivity(intent)
                        overridePendingTransition(0, 0)
                        Log.d("kjsfgxhufb", response.body()?.user_msg.toString())
                    } else {
                        try {
                            val jObjError = JSONObject(response.errorBody()!!.string())
                            Toast.makeText(applicationContext, jObjError.getString("message")   jObjError.getString("user_msg"),
                                    Toast.LENGTH_LONG).show()
                        } catch (e: Exception) {
                            Toast.makeText(applicationContext, e.message, Toast.LENGTH_LONG).show()
                            Log.e("errorrr", e.message)
                        }
                    }
                }
            })
}
  

API:

 @FormUrlEncoded
@POST("editCart")
fun editCart(
        @Header("access_token") token: String,
        @Field("product_id") product_id: Int,
        @Field("quantity") quantity: Array<Int>
): Call<DeleteResponse>
  

Приведенный выше код работает без реализации ViewModel.Он редактируется и получил успешный ответ

 with ViewModel implementation
  

ViewModel:

 class CartViewModel(context: Application, savedStateHandle: SavedStateHandle) :
    AndroidViewModel(context) {
    ///   val product_id:String?=null

    sealed class Result {
        object Missing : Result()

        object NetworkFailure : Result()

        object Success : Result()
    }

    val product_id: MutableLiveData<String> = savedStateHandle.getLiveData("product_id", "")

    var country =
        arrayOf(1, 2, 3, 4, 5, 6, 7, 8)

    private var Cart: MutableLiveData<CartResponse>? = null

    val CartList: MutableLiveData<CartResponse>?
        get() {

            if (Cart == null) {
                Cart = MutableLiveData<CartResponse>()
                loadCartList()
            }
            return Cart
        }

    private val loginResultEmitter = EventEmitter<CartViewModel.Result>()
    val Results: EventSource<CartViewModel.Result> = loginResultEmitter
    private fun loadCartList() {

        val token: String =
            SharedPrefManager.getInstance(
                getApplication()
            ).user.access_token.toString()
        RetrofitClient.instance.listcart(token).enqueue(object :
            Callback<CartResponse> {
            override fun onFailure(call: Call<CartResponse>, t: Throwable) {
                Toast.makeText(getApplication(), "falied", Toast.LENGTH_LONG).show()
            }

            override fun onResponse(
                call: Call<CartResponse>,
                response: Response<CartResponse>
            ) {

                if (response.isSuccessful) {

                    Cart!!.value = response.body()

                }
            }

        })

    }

    fun loaddelete() {
        val id = product_id.value!!.toString().trim()

        val token: String =
            SharedPrefManager.getInstance(getApplication()).user.access_token.toString()
        RetrofitClient.instance.deletecart(token, id)
            .enqueue(object : Callback<DeleteResponse> {
                override fun onFailure(call: Call<DeleteResponse>, t: Throwable) {
                    loginResultEmitter.emit(CartViewModel.Result.NetworkFailure)

                    Log.d("res", ""   t)


                }

                override fun onResponse(
                    call: Call<DeleteResponse>,
                    response: Response<DeleteResponse>
                ) {
                    var res = response


                    if (res.body()?.status == 200) {
                        Toast.makeText(
                            getApplication(),
                            res.body()?.message,
                            Toast.LENGTH_LONG
                        ).show()


                        loginResultEmitter.emit(CartViewModel.Result.Success)


                    } else {
                        try {
                            val jObjError =
                                JSONObject(response.errorBody()!!.string())
                            Toast.makeText(
                                getApplication(),
                                jObjError.getString("message")   jObjError.getString("user_msg"),
                                Toast.LENGTH_LONG
                            ).show()
                        } catch (e: Exception) {
                            Toast.makeText(getApplication(), e.message, Toast.LENGTH_LONG).show()
                            Log.e("errorrr", e.message)
                        }
                    }
                }
            })


    }

    fun loadEdit() {
        val id = product_id.value!!.toString().trim()
        val token: String =
            SharedPrefManager.getInstance(getApplication()).user.access_token.toString()
        RetrofitClient.instance.editCart(token, id.toInt(), country)
            .enqueue(object : Callback<DeleteResponse> {
                override fun onFailure(call: Call<DeleteResponse>, t: Throwable) {
                    Log.d("res", ""   t)
                }

                override fun onResponse(
                    call: Call<DeleteResponse>,
                    response: Response<DeleteResponse>
                ) {
                    var res = response
                    if (res.isSuccessful) {
                        Toast.makeText(getApplication(), res.body()?.user_msg, Toast.LENGTH_LONG)
                            .show()
                    } else {
                        try {
                            val jObjError = JSONObject(response.errorBody()!!.string())
                            Toast.makeText(getApplication(),
                                jObjError.getString("message")   jObjError.getString("user_msg"),
                                Toast.LENGTH_LONG
                            ).show()
                        } catch (e: Exception) {
                            Toast.makeText(getApplication(), e.message, Toast.LENGTH_LONG).show()
                            Log.e("errorrr", e.message)
                        }
                    }
                }
            })
    }
}
  

Активность:

 class AddToCart : BaseClassActivity(), OnItemClick {
    var progressDialog: ProgressDialog? = null
    private val viewModel by viewModels<CartViewModel>()
    var country =
        arrayOf(1, 2, 3, 4, 5, 6, 7, 8)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.add_to_cart)
        getWindow().setExitTransition(null)
        getWindow().setEnterTransition(null)
        val progressDialog: ProgressDialog = ProgressDialog(applicationContext);

        var mActionBarToolbar = findViewById<androidx.appcompat.widget.Toolbar>(R.id.toolbartable);
        setSupportActionBar(mActionBarToolbar);
        // add back arrow to toolbar
        setEnabledTitle()

        mActionBarToolbar.setNavigationOnClickListener(View.OnClickListener {
            onBackPressed()
        })
        placeorder.setOnClickListener {
            val intent: Intent = Intent(applicationContext, AddressActivity::class.java)
            startActivity(intent)
        }
        loadCart()
    }

    fun loadCart() {

        val model = ViewModelProvider(this)[CartViewModel::class.java]

        model.CartList?.observe(this, object : Observer<CartResponse> {
            override fun onChanged(t: CartResponse?) {

                generateDataList(t?.data?.toMutableList())
                totalamount.setText(t?.total.toString())
            }
        })
    }

    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.setItemClick(this);

        adapter.notifyDataSetChanged()
        if (dataList?.isEmpty() ?: true) {
            recyclerView?.setVisibility(View.GONE)
            totalamount.setVisibility(View.GONE)
            fl_footer.setVisibility(View.GONE)
            placeorder.setVisibility(View.GONE)
            emptytext.setVisibility(View.VISIBLE)
        } else {
            recyclerView?.setVisibility(View.VISIBLE)
            totalamount.setVisibility(View.VISIBLE)
            fl_footer.setVisibility(View.VISIBLE)
            placeorder.setVisibility(View.VISIBLE)
            emptytext.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)
        startActivity(intent)
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        return when (item.itemId) {
            android.R.id.home -> {
                NavUtils.navigateUpFromSameTask(this)

                true
            }
            else -> super.onOptionsItemSelected(item)
        }
    }

    override fun onResume() {
        super.onResume()
        loadCart()
    }


    override fun DeleteItem(position: Int, id: Int) {
  

    }

    override fun EditItem(position: Int, id: Int) {
        viewModel.product_id.value = id.toString()
        viewModel.loadEdit()
        viewModel.country[position] = country[position]
        viewModel.Results.observe(this) { result ->
            when (result) {
                CartViewModel.Result.Missing -> {
                    Toast.makeText(
                        applicationContext, "product is missing", Toast.LENGTH_LONG
                    ).show()
                }
                CartViewModel.Result.Success -> {
                    finish()
                    val intent = Intent(applicationContext, AddToCart::class.java)
                    intent.flags =
                        Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_MULTIPLE_TASK
                    startActivity(intent)
                    overridePendingTransition(0, 0)
                }
                else -> {
                    Toast.makeText(applicationContext, "hello", Toast.LENGTH_LONG).show()
                }
            }
        }

    }
}
  

Из реализации ViewModel я получаю ответ об успешном завершении в toast, означающий, что корзина была успешно обновлена, но когда я снова возвращаюсь к корзине, я вижу значение как 8 в счетчике.

Например, если я установлю счетчик как 3, он покажет успех (корзина успешно обновлена), но когда я возвращаюсь, я вижу 8 в счетчике.

Мне нужна помощь в правильном кодировании счетчика, чтобы он принимал правильное значение элемента, который я выбрал в счетчике при повторном просмотре.

Комментарии:

1. Если вы можете сделать так, чтобы ваш OnItemClick отображал элемент, а не позицию идентификатор, я думаю, вы можете упростить проблему. Я думаю viewModel.country[position]=country[position] , что это нарушает ваш код.

2. @EpicPandaForce если я отлажу эту строку viewModel.country[position]=country[position] и установлю счетчик как 3 …. отладчик показывает, что позиция равна 2, а идентификатор равен 14 …. это означает, что я получаю правильное положение счетчика, но он неправильно настроен и отправляет количество счетчиков в вызове

3. Если я сравниваю вызовы API из обеих реализаций, я вижу, что с реализацией ViewModel вы называете это: RetrofitClient.instance.editCart(token, id.toInt(), country) где country — это весь массив, а из предыдущей реализации я вижу это: RetrofitClient.instance.editCart(token, id, arrayOf(country[position])) . Может ли это быть возможной проблемой?

4. я так думаю … вот почему он всегда отправляет значение как 8 …???? но как мне получить позицию в viewmodel?? @JeelVankhede

5. Разве вы не можете передать его в методе в качестве параметра, подобного position: Int ?