在android中的适配器内进行改造调用

Posted

技术标签:

【中文标题】在android中的适配器内进行改造调用【英文标题】:Retrofit call inside an adapter in android 【发布时间】:2021-02-06 05:41:36 【问题描述】:

我正在适配器内执行改造调用..我已成功实施,并且它也给了我所需的输出,但 在适配器下执行此操作是否是一种好习惯?????

我的应用是-->产品销售应用-->在我的购物车中-->我正在显示用户想要购买的产品列表-->为此需要一个适配器-->我正在执行滑动删除功能-->在删除(holder.delete.setonclicklistener ...)按钮上执行改造调用

我的代码是-->

        holder.tvDelete.setOnClickListener(View.OnClickListener  view ->
        progressDialog.show()

        val token: String = SharedPrefManager.getInstance(context).user.access_token.toString()
        RetrofitClient.instance.deletecart(token, id.toString())
            .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
                    progressDialog.dismiss()
                    (context as Activity).finish()

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


                     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)

    )

上面的代码正在运行

我也经历过这个 --> passing data from on click function of my recycler adaptor

我执行了此链接,但在活动中我无法访问活动中的此代码

    mItemManger.removeShownLayouts(holder.swipelayout)
                        notifyItemChanged(position)
                        notifyItemRemoved(position)
                        dataList?.removeAt(position)
                        notifyItemRangeChanged(position, dataList?.size!!)
                        mItemManger.closeAllItems()

需要澄清一下

需要帮助,谢谢

编辑:--我按照上面的链接是我的代码

界面

interface OnItemClick 
fun onItemClicked(position: Int)

 

活动

class AddToCart:BaseClassActivity(), OnItemClick
override fun onCreate(savedInstanceState: Bundle?) 
    super.onCreate(savedInstanceState)
    setContentView(R.layout.add_to_cart)
    getWindow().setExitTransition(null)
    getWindow().setEnterTransition(null)
    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)))


    adapter.notifyDataSetChanged()
     adapter.setItemClick(this)
    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 onItemClicked(position: Int) 

    val token: String = SharedPrefManager.getInstance(applicationContext).user.access_token.toString()
    RetrofitClient.instance.deletecart(token, id.toString())
        .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
                (applicationContext as Activity).finish()

                if (res.body()?.status == 200) 
                    Toast.makeText(
                        applicationContext,
                        res.body()?.message,
                        Toast.LENGTH_LONG
                    ).show()
                    val intent =
                        Intent(applicationContext, AddToCart::class.java)
                    intent.flags =
                        Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_MULTIPLE_TASK
                    applicationContext.startActivity(intent)
                    (applicationContext as Activity?)!!.overridePendingTransition(0, 0)


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


   

适配器:--

class CartAdapter(private val context: Context, private val dataList: MutableList<DataCart?>?) :
RecyclerSwipeAdapter<CartAdapter.CustomViewHolder>() , AdapterView.OnItemSelectedListener //added RecyclerSwipeAdapter and override
private var itemClick: OnItemClick? = null

inner class CustomViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
    View.OnClickListener 
    val mView: View
  val swipelayout:SwipeLayout
    val productiamge: ImageView
    val productname: TextView
    val productcategory: TextView
    val productprice: TextView
    val tvDelete:TextView
    val spin:Spinner
    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)
        swipelayout=mView.findViewById(R.id.swipe)
        tvDelete=mView.findViewById(R.id.tvDelete)
         spin = mView.findViewById(R.id.spinner) as Spinner
        tvDelete.setClickable(true);
        tvDelete.setOnClickListener(this);

    

    override fun onClick(v: View?) 
        if (itemClick != null) 
            itemClick!!.onItemClicked(getPosition());
        
    




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.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.tvDelete.setOnClickListener(View.OnClickListener  view ->
        mItemManger.removeShownLayouts(holder.swipelayout)
        notifyItemChanged(position)
        notifyItemRemoved(position)
        dataList?.removeAt(position)
        notifyItemRangeChanged(position, dataList?.size!!)
        mItemManger.closeAllItems()
    )
    mItemManger.bindView(holder.itemView, position)



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

override fun onNothingSelected(p0: AdapterView<*>?) 
    TODO("Not yet implemented")


override fun onItemSelected(p0: AdapterView<*>?, p1: View?, p2: Int, p3: Long) 


fun getItemClick(): OnItemClick? 
    return itemClick


fun setItemClick(itemClick: OnItemClick?) 
    this.itemClick = itemClick

但我没有得到想要的输出帮助我

【问题讨论】:

"在适配器下执行此操作是一个好习惯吗??" - 理论说不,因为适配器+视图只必须显示数据并设置监听器,这就是全部(UI模块)。实现网络逻辑的责任是数据网络类,注入您的改造接口,如果您需要来自另一个数据源的另一个数据作为 SharedPreferences,您的存储库可以准备必要的数据来执行调用(数据模块)。如果您需要业务逻辑并且想要实现一个干净的架构,那么您可以创建一个域模块(用例 + 实体) @ManuelMato 你能看到修改后的代码吗 再走一步,你将把你正在做的事情转移到 ViewModel 中,这就是你想要完成的事情:) 从技术上讲,您可以将 ViewModel 传递给 Adapter,但我宁愿在 Adapter 中为项目单击定义一个接口,然后将其公开给 Fragment,Fragment 将调用 VM . 哇它成功了@EpicPandaForce 非常感谢..你总是帮助我:) :) 【参考方案1】:

在用户 EpicPandaForce 的帮助下,我得到了问题问题的答案

界面::----

interface OnItemClick 
fun DeleteItem(position: Int, id:Int)

适配器::----

    private var itemClick: OnItemClick? = null
     .
    .
     .
      holder.tvDelete.setOnClickListener(View.OnClickListener  view ->
        mItemManger.removeShownLayouts(holder.swipelayout)
        notifyItemChanged(position)
        notifyItemRemoved(position)
        dataList?.removeAt(position)
        itemClick?.DeleteItem(position,id!!.toInt())

        notifyItemRangeChanged(position, dataList?.size!!)
        mItemManger.closeAllItems()
    )
    mItemManger.bindView(holder.itemView, position)


    
    .
    .
     .
     
fun setItemClick(itemClick: OnItemClick?) 
    this.itemClick = itemClick

活动::----

class AddToCart:BaseClassActivity(), OnItemClick
 .
 .
  .
   onCreate()
            adapter.setItemClick(this);
       .
       .
       .
       
         override fun DeleteItem(position: Int, id:Int) 
    progressDialog?.show()
        viewModel.product_id.value =id.toString()
    viewModel.loaddelete()
    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()
            
        
    




视图模型::--------

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





【讨论】:

【参考方案2】:

这不是在适配器中进行 API 调用的好习惯。您可以创建从适配器到活动的回调,并且应该在活动本身中调用此 API 代码。如果您需要来自适配器的一些引用,那么您可以在适配器中创建方法并通过创建适配器的对象在活动中调用这些方法。

【讨论】:

我已经执行了这个 --> ***.com/a/32323801/14046751 但我无法在我的活动mItemManger.removeShownLayouts(holder.swipelayout) notifyItemChanged(position) notifyItemRemoved(position) dataList?.removeAt(position) notifyItemRangeChanged(position, dataList?.size!!) mItemManger.closeAllItems() 中访问此代码 您需要将此代码移动到适配器的方法并在类中调用该方法。 我在这条线上遇到错误 adapter.setItemClick(this); setItemClick 处为红色 这将填充错误,检查它在说什么。我猜你没有正确实现回调。或者你可以分享你的代码 让我们continue this discussion in chat。

以上是关于在android中的适配器内进行改造调用的主要内容,如果未能解决你的问题,请参考以下文章

如何在适配器内进行异步适配器调用

使用 RX And​​roid 进行并行 API 调用

自定义呼叫适配器改造中的通用类型

如何从android中的自定义适配器调用Activity asynctask

Android:从 viewPager 中的 Fragment 为 ListView 的适配器调用 getview()

RecyclerView:没有附加适配器;使用改造跳过应用程序中的布局[重复]