Material-calendarview set color de fondo de las fechas

Mi objetivo es encontrar una librería de Android que me permita marcar varias fechas en una vista de calendario basada en una matriz. Las fechas pueden o no ser contiguas. Mi escenario ideal es cambiar el color de fondo de cada fecha. La complicación significativa es que no conozco este color hasta el tiempo de ejecución, ya que vendrá de una consulta del servidor.

He estado investigando esto todo el día, y mi mejor esperanza parece ser material-calendarview ( github ). Sin embargo, estoy encontrando su código para ser algo impenetrable, que está en mí, pero estoy completamente atascado.

He añadido un calendario como este en mi diseño XML:

 <com.prolificinteractive.materialcalendarview.MaterialCalendarView android:id="@+id/calendar_view" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginLeft="20dp" android:layout_marginRight="20dp" xmlns:app="http://schemas.android.com/apk/res-auto" app:mcv_showOtherDates="all" app:mcv_selectionColor="#00F"/> 

Y luego en mi actividad, tengo estas variables de instancia:

 private MaterialCalendarView calendarView; private ArrayList<Date> markedDates; 

Y este código en mi onCreateView()

 calendarView = (MaterialCalendarView) view.findViewById(R.id.calendar_view); 

Ok, bastante fácil. Pero no puedo averiguar cómo marcar el calendario de mi matriz de fechas. Estoy trabajando en este método, pero no sé cómo proceder más allá de lo que tengo aquí:

 private void initializeCalendar() { calendarView.setOnDateChangedListener(context); calendarView.setShowOtherDates(MaterialCalendarView.SHOW_ALL); Calendar calendar = Calendar.getInstance(); calendarView.setSelectedDate(calendar.getTime()); calendar.set(calendar.get(Calendar.YEAR), Calendar.JANUARY, 1); calendarView.setMinimumDate(calendar.getTime()); calendar.set(calendar.get(Calendar.YEAR), Calendar.DECEMBER, 31); calendarView.setMaximumDate(calendar.getTime()); int bgColor = sharedVisualElements.getPrimaryColor(); calendarView.addDecorators(new EventDecorator(bgColor, ????)); } 

Esa última línea se refiere a esta clase interna:

 private class EventDecorator implements DayViewDecorator { private final int color; private final HashSet<CalendarDay> dates; public EventDecorator(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) { view.addSpan(new DotSpan(5, color)); } } 

Creo que mi desafío para convertir mi ArrayList<Date> markedDates a lo que llaman Collection<CalendarDay> dates . ¿De acuerdo? Pero aquí es donde realmente me turba. Esta estructura de datos es extraña para mí. Cuando intento instanciarlo llamando a new CalendarDay() mi clase se expande inmediatamente con unos 10 nuevos métodos que no entiendo su papel o qué hacer con ellos. Claramente, me voy de los rieles aquí. Simplemente no puede ser tan complicado.

¿Alguien ha utilizado esta biblioteca para este propósito y sabe cómo llevar a cabo esta tarea? Estoy en una parada de molienda. Además, si hay una biblioteca más simple que me permita establecer los colores de fondo con un color sólo se conoce en tiempo de ejecución, soy todos los oídos.

Gracias por cualquier ayuda. Me temo que he escrito esto de una manera confusa, que es el resultado del hecho de que estoy completamente confundido.

He resuelto esto, así que voy a publicar esa solución en caso de que alguien más tiene la misma pregunta. Si hay una manera más eficiente, por favor, publicar como una solución.

He mencionado que tengo una matriz con una lista de fechas. Lo que necesito hacer es iterar sobre esa matriz, convirtiendo cada Date en un objeto de Calendar establecido en el año, el mes y el día apropiados y añadiendo ese objeto a una ArrayList diferente, esta vez un ArrayList<CalendarDay> . Por ejemplo:

 List<CalendarDay> list = new ArrayList<CalendarDay>(); Calendar calendar = Calendar.getInstance(); for (Date date : markedDates) { // might be a more elegant way to do this part, but this is very explicit int year = date.getYear(); int month = date.getMonthOfYear() - 1; // months are 0-based in Calendar int day = date.getDayOfMonth(); calendar.set(year, month, day); CalendarDay calendarDay = CalendarDay.from(calendar); list.add(calendarDay); } 

Así que ahora tenemos esta lista de objetos de CalendarDay , pero no estamos completamente allí. El paso final en la creación de la estructura de datos es "convertir" esto a lo que he mencionado que estaba luchando con en el OP – una Collection<CalendarDay> estructura. Resulta que esto no podría ser más simple una vez que llegamos aquí. Simplemente asignalo de esta manera:

 calendarDays = list; 

Y luego, cuando quiera agregar el decorador, ya está todo preparado. Sólo haz esto:

 calendarView.addDecorators(new EventDecorator(myColor, calendarDays)); 

Otra cosa es mencionar, y esto fue una fuente importante de mi confusión. No he entendido cómo instanciar este objeto Collection<CalendarDay> . Camino hasta en la sección de variable de instancia (antes del constructor), he añadido este código, casi todos los cuales Android Studio llenado para mí:

 private Collection<CalendarDay> calendarDays = new Collection<CalendarDay>() { @Override public boolean add(CalendarDay object) { return false; } @Override public boolean addAll(Collection<? extends CalendarDay> collection) { return false; } @Override public void clear() { } @Override public boolean contains(Object object) { return false; } @Override public boolean containsAll(Collection<?> collection) { return false; } @Override public boolean isEmpty() { return false; } @NonNull @Override public Iterator<CalendarDay> iterator() { return null; } @Override public boolean remove(Object object) { return false; } @Override public boolean removeAll(Collection<?> collection) { return false; } @Override public boolean retainAll(Collection<?> collection) { return false; } @Override public int size() { return 0; } @NonNull @Override public Object[] toArray() { return new Object[0]; } @NonNull @Override public <T> T[] toArray(T[] array) { return null; } }; 

Espero que esto ayude a alguien. Una vez más, si hay una mejor solución, por favor, postear y voy a eliminar la mía.

¿Por qué utilizó ArrayList en lugar del HashSet? La razón por la que no se puede instanciar Colección es porque es una interfaz, por lo tanto, hay que crear una clase anónima y anular los métodos.

Aquí es cómo hice algo similar:

Este método tiene en dos objetos de calendario y agrega todos los días entre las dos fechas de calendario en un HashSet de CalendarDays.

 private HashSet<CalendarDay> getCalendarDaysSet(Calendar cal1, Calendar cal2) { HashSet<CalendarDay> setDays = new HashSet<>(); while (cal1.getTime().before(cal2.getTime())) { CalendarDay calDay = CalendarDay.from(cal1); setDays.add(calDay); cal1.add(Calendar.DATE, 1); } return setDays; } 

En el método onCreateView (…), he establecido dinámicamente las dos fechas de calendario, la diferencia entre las que se almacenarán en el HashSet. Sin embargo, puede pasar su propio conjunto aleatorio de fechas en el HashSet.

 Calendar cal1 = Calendar.getInstance(); cal1.set(2016, 8, 1); Calendar cal2 = Calendar.getInstance(); cal2.set(2016, 9, 1); HashSet<CalendarDay> setDays = getCalendarDaysSet(cal1, cal2); int myColor = R.color.red; mCalendarView.addDecorator(new BookingDecorator(myColor, setDays)); 

En mi caso, BookingDecorator es la clase que implementa la interfaz DayViewDecorator.

  private class BookingDecorator implements DayViewDecorator { private int mColor; private HashSet<CalendarDay> mCalendarDayCollection; public BookingDecorator(int color, HashSet<CalendarDay> calendarDayCollection) { mColor = color; mCalendarDayCollection = calendarDayCollection; } @Override public boolean shouldDecorate(CalendarDay day) { return mCalendarDayCollection.contains(day); } @Override public void decorate(DayViewFacade view) { view.addSpan(new ForegroundColorSpan(mColor)); //view.addSpan(new BackgroundColorSpan(Color.BLUE)); view.setBackgroundDrawable(ContextCompat.getDrawable(getContext(),R.drawable.greenbox)); } } 

Su mensaje fue muy útil. Espero que la mía ayude a alguien también.

Si desea cambiar el color de fondo de la programación seleccionada, utilice este método:

 MaterialCalendarView materialCalendar = (MaterialCalendarView)findViewById(R.id.materialCalenderView); materialCalendar.setSelectionColor(Color.parseColor("#00BCD4")); 

El uso de este código hace que todos los selectores del mismo color, por lo que si desea tener selectores de color diferentes dependiendo de su condición, use decorator ()

  • Android Studio Error: Error: CreateProcess error = 216, Esta versión de% 1 no es compatible con la versión de Windows que está ejecutando
  • RxJava y eventos esporádicos al azar en Android
  • Proteger la aplicación de la descompilación ocultando Manifest y convirtiendo el código en un carácter Unicode
  • Ejemplo sencillo de Android Scroller
  • ejecutando runOnUiThread en una clase separada
  • Pasar un LinkedHashMap <Objeto, Cadena> de una actividad a otra
  • 'RealmNoticeModelClass' tiene una clave primaria, use 'createObject (Class <E>, Object)' en su lugar
  • Es posible detener un subproceso que se está conectando a URL con httpConnection.connect ()?
  • Actualizar los contenidos de recyclerview fallan en la hoja inferior
  • Multiplicación básica de matriz en OpenCV para Android
  • Buena ingeniería de software vs. seguridad
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.