如何使用点击侦听器和后台工作者更改 android 视图的外观?



我有一个安卓应用程序,用户可以使用它在特定时间签入课程。他们的每日时间表在回收器视图上显示为一系列CardView。每个 CardView 都有每个班级的基本信息,包括教师姓名、课程标题、出勤状态等。 该应用程序通过从AsyncTask后台工作程序调用的php脚本与MySQL数据库通信。在 PostExecute 方法中,应用从 php 脚本接收结果(如果按时签到,则为"存在",如果延迟则为"延迟",如果完全错过,则为"缺席"(,以显示在 AlertDialog 中。PostExecute 方法还设置一个字符串变量以等于结果。

The background worker is called from a click listener like so:
baf.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int bright = status.getResources().getColor(R.color.colorPresent);
status.setBackgroundColor(bright);
lol = getAdapterPosition()+1;
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
Calendar c = Calendar.getInstance();
String time = sdf.format(c.getTime());
Log.d("Current Time",time);
String type="checkin";
PresentBackgroundWorker presentBackgroundWorker = new PresentBackgroundWorker(getActivity());
presentBackgroundWorker.execute(type,date,time, "t"+String.valueOf(lol));
String aaa = ontime;
status.setText(aaa);
}
});

变量ontime(全局变量(是 php 脚本的结果,其值由后台工作线程设置,如下所示:

protected void onPostExecute(String result) {
writeitout(result);
alertDialog.setMessage(result);

alertDialog.show();
}
private void writeitout(String string) {
ontime = string;
Log.d("STATS",ontime);
}

根据Log.d()命令,ontime 变量正在适当更改,但对"状态"文本视图的更改会延迟一次单击。也就是说,上一门课程的结果会显示在当前课程中。如何确保准时变量中的更改按时显示?

编辑:添加了原始课程适配器

public class CourseAdapter extends RecyclerView.Adapter<CourseAdapter.MyViewHolder> {
private List<Course> courseList;

public CourseAdapter(List<Course> sc) { this.courseList = sc; }
public class MyViewHolder extends  RecyclerView.ViewHolder {
TextView title, teacher, type, status;
FloatingActionButton baf;
View subIten;
int lol;
public MyViewHolder(View view) {
super(view);
title = (TextView) view.findViewById(R.id.texttitle);
teacher = (TextView) view.findViewById(R.id.textteach);
type = (TextView) view.findViewById(R.id.texttype);
baf = (FloatingActionButton) view.findViewById(R.id.fab);
status = view.findViewById(R.id.textstatus);
subIten = (View) view.findViewById(R.id.sub_item);
}
private void bind(Course course) {
title.setText(course.getTitle());
teacher.setText(course.getTeacher());
type.setText(course.getType());
baf.setImageResource(course.getPhotoID());
baf.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int bright = status.getResources().getColor(R.color.colorPresent);
status.setBackgroundColor(bright);
lol = getAdapterPosition()+1;
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
Calendar c = Calendar.getInstance();
String time = sdf.format(c.getTime());
Log.d("Current Time",time);
String type="checkin";
PresentBackgroundWorker presentBackgroundWorker = new PresentBackgroundWorker(getActivity());
presentBackgroundWorker.execute(type,date,time, "t"+String.valueOf(lol));
}
});
}
}
@Override
public CourseAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.cardview, parent, false);
MyViewHolder viewHolder = new MyViewHolder(itemView);
return viewHolder;
}
@Override
public void onBindViewHolder(final CourseAdapter.MyViewHolder holder, final int position) {
final Course course = courseList.get(position);
holder.bind(course);
}
public int getItemCount() {
return courseList.size();
}
}

问题是您将异步任务结果保存在变量中,然后在单击按钮时访问它。 所以,这里基本上发生了什么:

  1. 您单击一个按钮
  2. 你启动异步任务
  3. 您的异步任务仍在工作。因此,onTime仍然没有字符串。而且,status.setText(( 甚至在 asynctask 产生结果并将其保存在 onTime 中之前就被调用了。
  4. 您的 asynctask 已完成其作业并将结果保存在 onTime 中,但按钮已经完成了其余代码,因此 textView 不会获得最新的更改。
  5. 您再次单击按钮
  6. 你的 asynctask 再次开始工作,但这次 onTime 有一个值,因为上一个 asynctask 保存了它的结果。 所以当 status.setText(( 被调用时,它设置了 onTime 的值(它保存了上一个 asynctask 的结果(

因此,要解决此问题,您不应该在单击按钮时更新文本视图,而是在 asynctask 的 onPostExecute(( 中更新它们

只需像这样更改您的onPostExecute((,您就有了解决方案。

protected void onPostExecute(String result) {
writeitout(result);
status.setText(result); //updating the textview directly here
alertDialog.setMessage(result);
alertDialog.show();
}

另外,从您的 baf 点击侦听器中删除这两行

String aaa = ontime;
status.setText(aaa); 

最新更新