2015-11-04 14 views
8

Mein Ziel ist es, eine Android-Bibliothek zu finden, mit der ich verschiedene Daten in einer Kalenderansicht basierend auf einem Array markieren kann. Die Daten können oder können nicht zusammenhängend sein. Mein ideales Szenario ist, die Hintergrundfarbe jedes Datums zu ändern. Die wesentliche Komplikation ist, dass ich diese Farbe erst zur Laufzeit kenne, da sie von einer Serverabfrage kommt.material-calendarview set Hintergrundfarbe der Daten

Ich habe dies den ganzen Tag erforscht, und meine beste Hoffnung scheint zu sein material-calendarview (github). Allerdings finde ich ihren Code etwas undurchdringlich, was auf mich zutrifft, aber ich bin völlig festgefahren.

Ich habe einen Kalender wie dies in meinem XML-Layout hinzugefügt:

<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"/> 

Und dann in meiner Tätigkeit habe ich diese Instanzvariablen:

private MaterialCalendarView calendarView; 
private ArrayList<Date> markedDates; 

und diesen Code in meinem onCreateView()

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

Ok, einfach genug. Aber ich kann nicht herausfinden, wie ich den Kalender aus meiner Datenreihe markieren soll. Ich arbeite an dieser Methode, aber ich weiß einfach nicht, wie darüber hinaus gehen, was ich habe hier:

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, ????)); 
} 

Die letzte Zeile diese innere Klasse verweist:

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)); 
     } 
    } 

Ich denke, dass mein Herausforderung, meine ArrayList<Date> markedDates in das umzuwandeln, was sie Collection<CalendarDay> dates nennen. Zustimmen? Aber hier bin ich wirklich versaut. Diese data structure ist für mich seltsam. Wenn ich versuche, es zu instanziieren, indem ich new CalendarDay() aufruft, erweitert meine Klasse sofort mit ungefähr 10 neuen Methoden, die ich ihre Rolle oder was mit ihnen nicht verstehe. Klar, ich gehe hier von der Strecke. Es kann einfach nicht so schwierig sein.

Hat jemand diese Bibliothek für diesen Zweck verwendet und weiß, wie man diese Aufgabe erfüllt? Ich bin am Ende. Auch wenn es eine einfachere Bibliothek gibt, die es mir ermöglicht, Hintergrundfarben mit einer Farbe zu setzen, die nur zur Laufzeit bekannt ist, bin ich ganz Ohr.

Danke für jede Hilfe. Ich befürchte, dass ich dies auf verwirrende Weise geschrieben habe, was darauf zurückzuführen ist, dass ich völlig verwirrt bin.

Antwort

3

Ich löste das, also werde ich diese Lösung posten, falls jemand die gleiche Frage hat. Wenn es einen effizienteren Weg gibt, posten Sie bitte als Lösung.

Ich erwähnte, dass ich ein Array mit einer Liste von Daten habe. Was ich tun muss, ist über dieses Array zu iterieren, um jedes Date in ein Calendar Objekt zu konvertieren, das auf das entsprechende Jahr, den Monat und den Tag gesetzt wird, und dann dieses Objekt zu einem anderen ArrayList hinzufügt, diesmal ein ArrayList<CalendarDay>. Zum Beispiel:

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); 
} 

So, jetzt haben wir diese Liste von CalendarDay Objekten bekommen, aber wir sind nicht ganz da. Der letzte Schritt bei der Erstellung der Datenstruktur besteht darin, dies in das, was ich erwähnt habe, zu überführen, mit dem ich im OP kämpfte - eine Collection<CalendarDay> Struktur. Es stellte sich heraus, dass dies nicht einfacher sein könnte, sobald wir hier sind.weisen Sie einfach wie folgt aus:

calendarDays = list; 

Und dann, wenn Sie den Dekorateur hinzufügen möchten, sind Sie alle eingerichtet. Genau dies tut:

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

Eine andere Sache trägt zu erwähnen, und das war eine wichtige Quelle für meine Verwirrung. Ich habe nicht verstanden, wie man dieses Collection<CalendarDay> Objekt instanziiert. Weg nach oben in der Instanzvariable Abschnitt (vor dem Konstruktor), habe ich diesen Code hinzugefügt, von denen fast alle Android Studio in mir gefüllt:

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; 
     } 
    }; 

Ich hoffe, dass dies jemand hilft. Auch hier, wenn es eine bessere Lösung gibt, bitte posten und ich werde meine löschen.

+0

bro, wenn ich das tun, ist die getYear() veraltet, was kann ich tun, um das zu ersetzen –

2

Warum haben Sie die ArrayList anstelle des HashSet verwendet? Der Grund, warum Sie Collection nicht instanziieren können, ist, dass es eine Schnittstelle ist. Daher mussten Sie eine anonyme Klasse erstellen und die Methoden überschreiben.

Hier ist, wie ich habe etwas ähnliches:

Diese Methode nimmt in zwei Kalenderobjekte und fügt alle Tage zwischen den beiden Kalenderdaten in ein HashSet von 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; 
} 

am onCreateView (...) Methode I haben die beiden Kalenderdaten dynamisch festgelegt, wird die Differenz zwischen dem in dem HashSet gespeichert wird. Sie können jedoch Ihre eigenen zufälligen Daten im HashSet übergeben.

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)); 

In meinem Fall BookingDecorator ist die Klasse, die die DayViewDecorator-Schnittstelle implementiert.

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)); 

    } 
} 

Ihr Beitrag war sehr hilfreich. Hoffnung meins hilft auch jemandem.

3

Wenn Sie die Hintergrundfarbe des ausgewählten programmatisch ändern möchten, verwenden Sie diese Methode: -

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

diesem Code macht alle Selektoren von derselben Farbe, wenn Sie also auf verschiedenen Farbwähler je haben wollen Ihre Bedingung, verwenden Sie Dekorateur()

Verwandte Themen