如何在 RecyclerView 和 AsyncTask 中禁用按钮

Posted

技术标签:

【中文标题】如何在 RecyclerView 和 AsyncTask 中禁用按钮【英文标题】:How to disable button in RecyclerView and from AsyncTask 【发布时间】:2019-12-15 06:07:11 【问题描述】:

我试图在 RecyclerView 从 Retrofit 响应中单击后禁用按钮。

应用程序正在使用 RecyclerView 填充列表,而我正在使用 Retrofit 与后端 REST API 通信。一项内有两个按钮,点击即可激活 Retrofit 客户端。如果来自 API 的响应成功,则应禁用按钮。我遇到了两个问题: 前几个项目工作得很好,但是在我从未点击过的几个滚动按钮之后也被禁用; 其次是列表中的几个随机按钮仍然可以点击。

    public void onBindViewHolder(final NewsViewHolder holder, int position) 
        holder.btnPositive.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
//              init Retrofit Client
                JSONPlaceHolderAPI mAPIService;
                mAPIService = ApiUtils.getAPIServiceFetch();
                mAPIService.getNews(url).enqueue(new Callback<Result>() 
                    @Override
                    public void onResponse(Call<Result> call, Response<Result> 
                                           response) 
                            holder.btnPositive.setVisibility(View.GONE);
                        
                    
                    @Override
                    public void onFailure(Call<Result> call, Throwable t) 
//                      do code
                    
                );

            
        );
        holder.btnNegative.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                JSONPlaceHolderAPI mAPIService;
                mAPIService = ApiUtils.getAPIServiceFetch();
                mAPIService.getNews(url).enqueue(new Callback<Result>() 
                    @Override
                    public void onResponse(Call<Result> call, Response<Result> 
                                           response) 
                            holder.btnNegative.setEnabled(false);
                        
                    
                    @Override
                    public void onFailure(Call<Result> call, Throwable t) 
                    // do code
                    
                );

            
        );
    

我想问题出在 Retrofit 的某个地方,它使用后台线程或 AsyncTask。

【问题讨论】:

【参考方案1】:

这发生在回收器视图回收(顾名思义)对您可见的视图并为导致此问题的每组项目提供相同的一组 ID。

这个问题有两种解决方案:

1) 停止recyclerview的回收行为如下:-

     @Override
public void onBindViewHolder(@NonNull MyViewHolder myViewHolder, int i) 
    myViewHolder.setIsRecyclable(false);

但我强烈否认使用这个原因回收是我们使用recyclerview的原因。

2) 使用 POJO 类:-

最好的解决方案是使用一个 POJO 类,它有两个变量,第一个是值,第二个是布尔变量,显示项目是否禁用。将您想要禁用的项目的 POJO 布尔变量的值设置为 true,并且在 onBindViewHolder 方法中仅禁用布尔变量中设置为 false 的项目的按钮。

如果您仍然感到困惑,请联系我,我会给您发送一个示例。

【讨论】:

我不再那么困惑了,但我想看看例子。当然,第一个解决方案不是一种选择。哪种方法会更好,像@faranjit 所说的那样制作列表或制作 POJO 类?在我看来,这是一回事。 是的,两者都是一样的,但是创建一个 POJO 是一个更好的选择,因为你总是可以移动一个 POJO 数组列表(使 POJO 类可序列化或可打包)与活动之间的所有数据同时维护其他数组列表会更多烦人的工作。如果您认为答案是正确的,请投票并将其标记为正确@IvanZ。 我可以看一个例子吗?谢谢。 :) 将尽快发布链接 1drv.ms/u/s!AvceoMt7FbgGad2MWJVuGfY6iSM?e=2K37nI 这是该项目的链接,请随时与我联系@shahaashit26@gmail.com。并对您认为适合社区的答案进行投票并将其标记为正确。谢谢【参考方案2】:

您需要保持这些按钮的状态。您可以在填充 recyclerview 的列表的项目(例如isNegativeEnabledwillPositiveDisplay 等)中保存状态。当您单击肯定按钮时,将 willPositiveDisplay 更改为 false。

list[position].willPositiveDisplay = false;

并检查list[position].willPositiveDisplay 是否为真,将可见性设置为可见,如果未设置为消失。并为否定按钮执行此操作。

【讨论】:

以上是关于如何在 RecyclerView 和 AsyncTask 中禁用按钮的主要内容,如果未能解决你的问题,请参考以下文章

如何通过单击两个按钮在单个活动中在 RecyclerView 和 ListView 之间切换?

如何在 RecyclerView 中选择位置?

如何从 recyclerview 裁剪图像并使用新裁剪的图像更新 recyclerview?

如何从RecyclerView项中获取Value

如何在 RecyclerView 中对字符串元素进行排序?

如何使用 Room 和 LiveData 保持 RecyclerView 顺序的更改?