问题
I am trying to disable button after click in RecyclerView from Retrofit response.
Application is using RecyclerView to populate list and I am using Retrofit to communicate to back-end REST API. There are two buttons inside one item and Retrofit client is activated on click. And if response from API is successful button should be disabled. I came across on two problems: first few items works just fine, but after few scrolls buttons I have never clicked on are disabled also; second was that little few random buttons further on in list are still clickable.
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
}
});
}
});
}
I suppose problem is somewhere in Retrofit where it uses background threads or AsyncTask.
回答1:
This happens as the recycler view recycles(as the name suggests) the view that is visible to you and gives the same set of ids to every set of items which causes this problem .
This problem has 2 solution :
1) Stop the recycle behaviour of recyclerview as follows:-
@Override
public void onBindViewHolder(@NonNull MyViewHolder myViewHolder, int i) {
myViewHolder.setIsRecyclable(false);
}
But i strongly deny to use this cause recycling is reason why we use recyclerview.
2) Using a POJO Class:-
The best solution for it is to use a POJO class which will have two variables the first one is value and the second one is a boolean variable which show is the item disabled or not . Set the value of POJO boolean variable to true for the items u want to disable and in onBindViewHolder method only disable the buttons for the items which has false set in boolean variable .
If you still are confused contact me i will send you an example of it .
回答2:
You need to hold states of those buttons. You can hold states in items(such as isNegativeEnabled
, willPositiveDisplay
etc.) of the list that populates recyclerview. When you click positive button, change willPositiveDisplay
to false.
list[position].willPositiveDisplay = false;
And check list[position].willPositiveDisplay
is true set visibility as visible, if not set as gone. And do this for negative button.
来源:https://stackoverflow.com/questions/57397181/how-to-disable-button-in-recyclerview-and-from-asynctask