用户交互后,如何根据 RecyclerView 适配器内服务器的响应更新 TextView?
How to update TextView based on response from server inside RecyclerView adapter after user interaction?
我试图通过读取服务器的响应来确定用户是否喜欢 post,在 Retrofit.call.enqueue() 中相应地为布尔值赋值并更改 UI's如果为真,则 TextView 值为 +1。我如何在多个回调中保存变量的值并在调用完成后根据它更新 UI?
在 UI 中,我在 RecyclerView 适配器中有两个按钮 (like\dislike),它们在单击后将数据更新到 MySQL 数据库,我正在尝试更新喜欢或不喜欢的数量用户互动(如果用户尚未投票,则为+1,我通过 Retrofit 调用进行检查)。
我试图在 Adapter class 中为全局变量赋值,但是代码
在调用完成之前运行(我假设这是因为 Retrofit 默认情况下在单独的线程中运行)。
我还尝试在 onPostExecute() 方法中更新 AsyncTask 中的 UI,如下所示:
private class LoadDataAsyncTask extends AsyncTask<String, Void, Boolean> {
//variable to be updated based on response
boolean voted = true;
public LoadDataAsyncTask() {
//todo
}
@Override
protected Boolean doInBackground(String... params) {
Log.v("Voted state start", String.valueOf(voted));
GetUserVotes mApiGetUserVotes;
mApiGetUserVotes = ApiUtils.getAPIServiceUserVotes();
mApiGetUserVotes.getVotes().enqueue(new Callback<ResultVotes>() {
@Override
public void onResponse(Call<ResultVotes> call, Response<ResultVotes> response) {
if(response.body().getSuccess()==1)
voted = true;
else
voted = false;
if(!voted){
//todo
} else {
Log.v("Voted", String.valueOf(voted));
//todo
}
}
@Override
public void onFailure(Call<ResultVotes> call, Throwable t) {
}
});
Log.v("Voted state end", String.valueOf(voted));
return voted;
}
@Override
protected void onPostExecute(Boolean result) {
Log.v("Voted state", String.valueOf(result));
if(result) {
//todo
} else {
//update UI TextView to +1 vote
Log.v("onPostExecution", "Triggered");
}
}
}
结果是:
1. V/Voted state start: false
2. V/Voted state end: false
3. V/Voted state: false
4. V/onPostExecution: Triggered
5. V/Voted: true
应该看起来像(如果投票):
1. false
2. true
3. true
4. Triggered
5. true
我也尝试过这样的界面:
public interface ResponseListener {
void onSuccess();
void onFail();
}
并在适配器 class 中实现它(如果未投票则为 onFail()):
@Override
public void onBindViewHolder(final NewsViewHolder holder, int position) {
final int iLikes = list.get(position).getPositiveVotes();
final int iDislikes = list.get(position).getNegativeVotes();
final ResponseListener retrofitResponseListener = new ResponseListener() {
@Override
public void onSuccess() {
}
@Override
public void onFail() {
int x = iNegativeVotes + 1;
holder.textViewDislike.setText(String.valueOf(x));
}
};
}
这是代码片段:
@Override
public void onBindViewHolder(final NewsViewHolder holder, int position) {
final int iLikes = list.get(position).getPositiveVotes();
final int iDislikes = list.get(position).getNegativeVotes();
holder.btnPositive.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final boolean[] voted = {false};
GetUserVotes mApiGetUserVotes;
mApiGetUserVotes = ApiUtils.getAPIServiceUserVotes();
mApiGetUserVotes.getVotes(email, url).enqueue(new Callback<ResultVotes>() {
@Override
public void onResponse(Call<ResultVotes> call, Response<ResultVotes> response) {
if(response.body().getSuccess()==1){
voted[0] = true;
}else{ voted[0] = false; }
if(!voted[0]){
//this is not working
holder.textViewDislike.setText(String.valueOf(x));
} else {
//do not update TextView
}
}
@Override
public void onFailure(Call<ResultVotes> call, Throwable t) {
}
});
}
});
}
如何根据 Retrofit 响应在单击按钮后更新 TextView 值?
听说有个东西叫'Callback hell',请问是什么东西,如何有效避免?
您不需要任何全局变量和回调。
刚刚在您的适配器中声明了一个 public 方法,它只更新您的适配器列表。您只需要更新项目的位置。
更新点赞数:
public void updateLikes(int pos){
int iLikes = list.get(position).getPositiveVotes();
iLikes++;
list.get(position).setPositiveVotes(iLikes);
notifyDataSetChanged(); // very important
}
更新不喜欢:
public void updateDislikes(int pos){
int iDislikes = list.get(position).getNegativeVotes();
iDislikes ++;
list.get(position).setNegativeVotes(iDislikes);
notifyDataSetChanged(); // very important
}
在您的改造或 Aysn 成功调用中,只需调用这些方法:
adapter.updateLikes(position) or adapter.updateDislikes(position)
我试图通过读取服务器的响应来确定用户是否喜欢 post,在 Retrofit.call.enqueue() 中相应地为布尔值赋值并更改 UI's如果为真,则 TextView 值为 +1。我如何在多个回调中保存变量的值并在调用完成后根据它更新 UI?
在 UI 中,我在 RecyclerView 适配器中有两个按钮 (like\dislike),它们在单击后将数据更新到 MySQL 数据库,我正在尝试更新喜欢或不喜欢的数量用户互动(如果用户尚未投票,则为+1,我通过 Retrofit 调用进行检查)。
我试图在 Adapter class 中为全局变量赋值,但是代码 在调用完成之前运行(我假设这是因为 Retrofit 默认情况下在单独的线程中运行)。 我还尝试在 onPostExecute() 方法中更新 AsyncTask 中的 UI,如下所示:
private class LoadDataAsyncTask extends AsyncTask<String, Void, Boolean> {
//variable to be updated based on response
boolean voted = true;
public LoadDataAsyncTask() {
//todo
}
@Override
protected Boolean doInBackground(String... params) {
Log.v("Voted state start", String.valueOf(voted));
GetUserVotes mApiGetUserVotes;
mApiGetUserVotes = ApiUtils.getAPIServiceUserVotes();
mApiGetUserVotes.getVotes().enqueue(new Callback<ResultVotes>() {
@Override
public void onResponse(Call<ResultVotes> call, Response<ResultVotes> response) {
if(response.body().getSuccess()==1)
voted = true;
else
voted = false;
if(!voted){
//todo
} else {
Log.v("Voted", String.valueOf(voted));
//todo
}
}
@Override
public void onFailure(Call<ResultVotes> call, Throwable t) {
}
});
Log.v("Voted state end", String.valueOf(voted));
return voted;
}
@Override
protected void onPostExecute(Boolean result) {
Log.v("Voted state", String.valueOf(result));
if(result) {
//todo
} else {
//update UI TextView to +1 vote
Log.v("onPostExecution", "Triggered");
}
}
}
结果是:
1. V/Voted state start: false
2. V/Voted state end: false
3. V/Voted state: false
4. V/onPostExecution: Triggered
5. V/Voted: true
应该看起来像(如果投票):
1. false
2. true
3. true
4. Triggered
5. true
我也尝试过这样的界面:
public interface ResponseListener {
void onSuccess();
void onFail();
}
并在适配器 class 中实现它(如果未投票则为 onFail()):
@Override
public void onBindViewHolder(final NewsViewHolder holder, int position) {
final int iLikes = list.get(position).getPositiveVotes();
final int iDislikes = list.get(position).getNegativeVotes();
final ResponseListener retrofitResponseListener = new ResponseListener() {
@Override
public void onSuccess() {
}
@Override
public void onFail() {
int x = iNegativeVotes + 1;
holder.textViewDislike.setText(String.valueOf(x));
}
};
}
这是代码片段:
@Override
public void onBindViewHolder(final NewsViewHolder holder, int position) {
final int iLikes = list.get(position).getPositiveVotes();
final int iDislikes = list.get(position).getNegativeVotes();
holder.btnPositive.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final boolean[] voted = {false};
GetUserVotes mApiGetUserVotes;
mApiGetUserVotes = ApiUtils.getAPIServiceUserVotes();
mApiGetUserVotes.getVotes(email, url).enqueue(new Callback<ResultVotes>() {
@Override
public void onResponse(Call<ResultVotes> call, Response<ResultVotes> response) {
if(response.body().getSuccess()==1){
voted[0] = true;
}else{ voted[0] = false; }
if(!voted[0]){
//this is not working
holder.textViewDislike.setText(String.valueOf(x));
} else {
//do not update TextView
}
}
@Override
public void onFailure(Call<ResultVotes> call, Throwable t) {
}
});
}
});
}
如何根据 Retrofit 响应在单击按钮后更新 TextView 值?
听说有个东西叫'Callback hell',请问是什么东西,如何有效避免?
您不需要任何全局变量和回调。
刚刚在您的适配器中声明了一个 public 方法,它只更新您的适配器列表。您只需要更新项目的位置。
更新点赞数:
public void updateLikes(int pos){
int iLikes = list.get(position).getPositiveVotes();
iLikes++;
list.get(position).setPositiveVotes(iLikes);
notifyDataSetChanged(); // very important
}
更新不喜欢:
public void updateDislikes(int pos){
int iDislikes = list.get(position).getNegativeVotes();
iDislikes ++;
list.get(position).setNegativeVotes(iDislikes);
notifyDataSetChanged(); // very important
}
在您的改造或 Aysn 成功调用中,只需调用这些方法:
adapter.updateLikes(position) or adapter.updateDislikes(position)