我有一个按需要工作的日历用户界面(material-calendarview)。当用户选择日期时,我正在更改该特定日期的背景颜色,然后我将该日历片段替换为另一个片段。一切正常。
我想要做的是在日历背景颜色更新后显示轻微停顿。由于它现在正常工作,您只能在替换片段之前看到背景颜色闪烁颜色变化。颜色变化几乎察觉不到。
以下是修改此单元格的代码:
calendarView.setOnDateChangedListener(new OnDateSelectedListener() {
@Override
public void onDateSelected(@NonNull MaterialCalendarView materialCalendarView, @NonNull CalendarDay calendarDay, boolean b) {
decorateSelectedDate(calendarDay.getDate());
// some other database stuff happens here
}
});
private void decorateSelectedDate(Date date) {
List<CalendarDay> list = new ArrayList<CalendarDay>();
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
CalendarDay calendarDay = CalendarDay.from(calendar);
list.add(calendarDay);
calendarDays = list;
calendarView.addDecorators(new SelectionDecorator(Color.RED, calendarDays));
}
private class SelectionDecorator implements DayViewDecorator {
// the point of this class is fill in the background color for the calendar cell
// just selected by the user
private final int color;
private final HashSet<CalendarDay> dates;
public SelectionDecorator(int color, Collection<CalendarDay> dates) {
this.color = color;
this.dates = new HashSet<>(dates);
}
@Override
public boolean shouldDecorate(CalendarDay day) {
return dates.contains(day);
}
@Override
public void decorate(DayViewFacade view) {
// colors the entire calendar space
Drawable drawable = new ColorDrawable(color);
view.setBackgroundDrawable(drawable);
// my attempt to add a short delay before replacing the fragments. 5 seconds is way too long, but I'm just trying to prove that this works.
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// this invokes a method in the activity to swap out the fragments
fragmentCommunicator.onNewDateSet();
}
}
您可以在更新UI的命令后立即看到我有一个Thread.sleep
命令。但是,无论我设置多长时间,延迟都会在 UI更新之前发生(应该是相反的),因此背景颜色变化在片段之前仍然只是一个闪光被替换了。
如何在开始延迟之前让UI更新?显然Thread.sleep
似乎不是答案。
谢谢!
答案 0 :(得分:2)
礼貌Handler
您可以使用处理程序代替线程
Handler允许您与其他人的UI线程进行通信 背景线程。这在Android中很有用,因为android不允许 其他线程直接与UI线程通信。处理程序可以发送 并处理与线程关联的Message和Runnable对象 的MessageQueue。每个Handler实例都与一个线程相关联 和那个线程的消息队列。创建新的Handler时,它就是 绑定到正在创建它的线程的线程/消息队列。
Handler handler = new Handler(); // Declare
handler.postDelayed(new Runnable() {
@Override
public void run() {
//Do something after your times
handler.postDelayed(this, Your_Delay_Time_INT);
}
}, 1500);
答案 1 :(得分:1)
你应该使用Handler.postDelayed(runnable,delay)推迟你的行动而不是睡觉。一般来说,将UI线程置于睡眠状态是一件坏事,应该避免使用。
有关详细信息,请参阅the docs。
在延迟的runnable中调用片段通信器。睡眠不起作用,因为设置的背景不是同步的(工作是指从点击返回后发生的下一次绘制调用),必须在与您正在睡觉的线程相同的线程上完成,以及一个运行片段操作。
答案 2 :(得分:1)
如果要更改UI,则无法使用此线程。您可以使用UIHandler或Handler。像这样:
Runnable run = new Runnable() {
@oberride
public void run(){
fragmentCommunicator.onNewDateSet();
}
};
view.postDelayed(run, 5000);
你想延迟什么,你应该把你的代码放在这个run()中。并且考虑到当用户在这5s运行时,你还需要写一个取消延迟。
答案 3 :(得分:0)
您可能想尝试使用Handle来运行可运行的