2015-11-05 5 views
2

У меня есть пользовательский интерфейс календаря (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(); 
     } 
    } 

Вы можете видеть, что у меня есть команда Thread.sleep сразу после команды для обновления пользовательского интерфейса. Однако независимо от того, сколько времени задержки я установил, происходит задержка до, пользовательский интерфейс обновляется (это должно быть наоборот), поэтому изменение цвета фона остается только вспышкой перед заменой фрагмента.

Как я могу получить UI для обновления до Задержка запуска? Очевидно, Thread.sleep, похоже, не является ответом.

Спасибо!

ответ

1

Вы должны использовать Handler.postDelayed (runnable, delay), чтобы отложить действие, а не спать. Вообще говоря, установка потока пользовательского интерфейса - это плохо, и его следует избегать.

См. the docs для получения дополнительной информации.

Положите свой вызов на коммуникатор фрагмента в задержанном исполнении. Сон не работает, потому что заданный фон не является синхронным (работа откладывается до следующего вызова розыгрыша, который происходит после того, как вы возвращаетесь с клика) и должен выполняться в том же потоке, что и тот, который вы спите, а также тот, который работает операции фрагмента.

+0

Got it. Благодаря! – Alex

0

Вы можете попробовать использовать ручку, чтобы запустить работоспособную

2

Предоставлено Handler

Вы можете использовать обработчик вместо ниток

обработчик позволяет общаться назад с Пользовательский интерфейс от других фон. Это полезно в Android, так как андроид не позволяет другим потокам общаться напрямую с потоком пользовательского интерфейса. Обработчик может отправить и обрабатывать сообщения Message and Runnable, связанные с сообщением Message. Каждый экземпляр 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); 
  • Хотя перепланирования Handler очень легко
+1

Спасибо. Почему у вас есть строка 'handler.postDelayed (this, Your_Delay_Time_INT' * внутри *« Runnable »? Не уже ли определена задержка, определенная на внешнем дескрипторе функции? – Alex

+1

Это снова перенесет ту же самую runnable. часто повторяться с пользовательским интерфейсом, это может быть удобным трюком. Хотя это может быть не идеальным способом для коротких или интервальных критических повторов – TrevJonez

1

Если вы хотите изменить пользовательский интерфейс, вы не можете использовать эту тему. Вы можете использовать UIHandler или Handler. Например:

Runnable run = new Runnable() { 
    @oberride 
    public void run(){ 
    fragmentCommunicator.onNewDateSet(); 
    } 
}; 

view.postDelayed(run, 5000); 

Что вы хотите отложить, вы должны поместить свой код в этот прогон(). И подумайте, когда пользователи будут работать в течение этих 5 секунд, вам также потребуется написать задержку отсрочки.

Смежные вопросы