UI更新后暂停

时间:2015-11-05 05:12:12

标签: android user-interface android-fragments

我有一个按需要工作的日历用户界面(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似乎不是答案。

谢谢!

4 个答案:

答案 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来运行可运行的