material-calendarview set background couleur des dates

mon but est de trouver une bibliothèque Android qui me permettra de marquer différentes dates sur un calendrier basé sur un tableau. Les dates peuvent être contiguës ou non. Mon scénario idéal est de changer la couleur de fond de chaque jour. La complication importante est que je ne connais pas cette couleur avant l'exécution, car elle proviendra d'une requête du serveur.

j'ai fait des recherches toute la journée, et mon meilleur espoir semble être material-calendarview ( github). Cependant, je suis à la recherche de leur code d'être un peu impénétrable, ce qui est sur moi, mais je suis complètement coincé.

j'ai ajouté un calendrier comme celui-ci dans ma mise en page 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"/>

puis dans mon activité, j'ai ces variables d'instance:

private MaterialCalendarView calendarView;
private ArrayList<Date> markedDates;

et ce code dans mon onCreateView()

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

Ok, assez facile. Mais je ne sais pas comment marquer le calendrier à partir de mon tableau de dates. Je travaille sur cette méthode, mais je ne sais pas comment procéder au-delà de ce que j'ai ici:

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

cette dernière ligne fait référence à cette classe intérieure:

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

je pense que mon défi pour convertir mes ArrayList<Date> markedDates pour ce qu'ils appellent Collection<CalendarDay> dates. D'accord? Mais c'est là que j'ai vraiment ralentir. Ce structure des données est bizarre pour moi. Lorsque j'essaie d'instancier en appelant new CalendarDay() ma classe s'étend immédiatement avec environ 10 nouvelles méthodes que je ne comprends pas leur rôle ou ce qu'il faut en faire. Clairement, je vais sur les rails d'ici. Il vient de ne peut pas être cette délicate.

quelqu'un A utilisé cette bibliothèque à cette fin et de savoir comment accomplir cette tâche? Je suis à une halte de meulage. En outre, s'il y a une bibliothèque plus simple pour me permettre de définir des couleurs de fond en utilisant une couleur seulement connu à l'exécution-temps, je suis toutes les oreilles.

merci de votre aide. Je crains d'avoir écrit cela d'une manière confuse, qui est le résultat du fait que je suis complètement confus.

10
demandé sur Alex 2015-11-04 05:31:04

3 réponses

si vous voulez changer la couleur de fond du programme sélectionné, utilisez cette méthode: -

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

L'utilisation de ce code rend tous les sélecteurs de la même couleur, donc si vous voulez avoir des sélecteurs de couleur différents selon votre condition, utilisez decorator()

4
répondu Mrinmoy 2016-09-09 06:11:09

j'ai résolu ceci, donc je vais poster cette solution au cas où quelqu'un d'autre aurait la même question. S'il ya une façon plus efficace, s'il vous plaît poster comme une solution.

je l'ai mentionné que j'ai un tableau avec une liste de dates. Ce que je dois faire est d'itérer sur ce tableau, en convertissant chaque Date dans un Calendar l'objet est défini à l'année, au mois et au jour appropriés, et ajoute ensuite cet objet à un ArrayList, cette fois, une ArrayList<CalendarDay>. Par exemple:

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

alors maintenant nous avons cette liste de CalendarDay objets, mais nous ne sommes pas tout à fait là. La dernière étape dans la création de la structure de données est de "convertir" cela à ce que j'ai mentionné que je me débattais dans L'OP - a Collection<CalendarDay> structure. Il s'avère que ça ne pourrait pas être plus simple une fois qu'on sera là. Assignez-le simplement comme ceci:

calendarDays = list;

et quand vous voulez ajouter le décorateur, tout est prêt. Faites simplement ceci:

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

une autre chose mérite d'être mentionnée, et c'était une source majeure de ma confusion. Je ne comprenais pas comment instancier cette Collection<CalendarDay> objet. Bien plus haut dans la section variable d'instance (avant le constructeur), j'ai ajouté ce code, presque tout ce que Android Studio a rempli pour moi:

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

j'espère que cela aide quelqu'un. Encore une fois, s'il ya une meilleure solution, s'il vous plaît poster et je vais supprimer la mienne.

3
répondu Alex 2015-11-04 07:34:45

Pourquoi avez-vous utilisé L'ArrayList au lieu du HashSet ? La raison pour laquelle vous ne pouvez pas instancier Collection est parce que c'est une interface, donc vous avez dû créer une classe anonyme et outrepasser les méthodes.

Voici comment j'ai fait quelque chose de similaire:

cette méthode prend deux objets de calendrier et ajoute tous les jours entre les deux dates de calendrier dans un HashSet de calendriers.

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

sur le onCreateView(... méthode,j'ai défini dynamiquement les deux dates de calendrier, la différence entre lequel sera stocké dans le HashSet. Toutefois, vous pouvez passer votre propre ensemble aléatoire de dates dans le 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));

dans mon cas BookingDecorator est la classe qui implémente L'interface 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));

    }
}

Votre message a été très utile. J'espère que le mien aidera aussi quelqu'un.

2
répondu Sameer Khanal 2016-08-12 04:40:01