我有一个安卓应用程序,用户可以使用它在特定时间签入课程。他们的每日时间表在回收器视图上显示为一系列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();
}
}
问题是您将异步任务结果保存在变量中,然后在单击按钮时访问它。 所以,这里基本上发生了什么:
- 您单击一个按钮
- 你启动异步任务
- 您的异步任务仍在工作。因此,onTime仍然没有字符串。而且,status.setText(( 甚至在 asynctask 产生结果并将其保存在 onTime 中之前就被调用了。
- 您的 asynctask 已完成其作业并将结果保存在 onTime 中,但按钮已经完成了其余代码,因此 textView 不会获得最新的更改。
- 您再次单击按钮
- 你的 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);