2015-11-04 182 views
8

我的目標是找到一個Android庫,它將允許我在基於數組的日曆視圖上標記各種日期。日期可能會連續或不連續。我的理想場景是更改每個日期的背景顏色。重要的複雜性是,我不知道這種顏色,直到運行時,因爲它將來自服務器查詢。material-calendarview設置日期的背景顏色

我一直在研究這一整天,我的最大希望似乎是material-calendarviewgithub)。但是,我發現他們的代碼有點難以理解,這對我來說很難,但我完全陷入了困境。

我添加了這樣的日曆在我的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"/> 

然後在我的活動,我有這方面的實例變量:

private MaterialCalendarView calendarView; 
private ArrayList<Date> markedDates; 

這個代碼我onCreateView()

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

好吧,很簡單。但我無法弄清楚如何從日期數組中標記日曆。我工作的這個方法,但我只是不知道如何着手超越了我這裏有:

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

最後一行是指這個內部類:

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

我認爲我的挑戰將我的ArrayList<Date> markedDates轉換爲他們所謂的Collection<CalendarDay> dates。同意?但這是我真正陷入困境的地方。這data structure是我的奇怪。當我嘗試通過調用new CalendarDay()來實例化它時,我的類立即用大約10種新方法進行擴展,我不明白它們的作用或如何處理它們。顯然,我在這裏脫軌。它不能是這個棘手。

有沒有人爲此目的使用此庫並知道如何完成此任務?我正在停下來。另外,如果有一個更簡單的庫允許我使用僅在運行時已知的顏色設置背景顏色,那麼我就是全部耳朵。

感謝您的任何幫助。我擔心我以混亂的方式寫下這些,這是我完全困惑的結果。

回答

3

我解決了這個問題,所以我會發布解決方案,以防其他人有相同的問題。如果有更有效的方法,請作爲解決方案發布。

我提到我有一個包含日期列表的數組。我需要做的是遍歷該數組,將每個Date轉換爲Calendar對象設置爲適當的年份,月份和日期,然後將該對象添加到不同的ArrayList,這次是ArrayList<CalendarDay>。例如:

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

所以,現在我們已經有了CalendarDay對象的這份名單,但我們也不能令人信服。創建數據結構的最後一步是將其轉換爲我所提到的我在OP中遇到的難題 - Collection<CalendarDay>結構。事實證明,一旦我們到達這裏,這不會變得更簡單。簡單地這樣分配它:

calendarDays = list; 

然後,當你想添加裝飾器,你都成立了。只是這樣做:

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

另一件事情值得一提,這是我的困惑的主要來源。我不明白如何實例化這個Collection<CalendarDay>對象。在(前的構造函數)的實例變量節路的時候,我加入這個代碼,幾乎所有的Android Studio中充滿對我來說:

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

我希望這可以幫助別人。再次,如果有更好的解決方案,請發佈,我會刪除我的。

+0

兄弟當我這樣做getYear()已棄用我可以做些什麼來代替 –

2

爲什麼使用ArrayList而不是HashSet? 您無法實例化Collection的原因是因爲它是一個接口,因此您必須創建匿名類並重寫這些方法。

這裏是我做了類似的事情:

這種方法需要在兩個日曆對象,並增加了所有日子的兩個日曆日期之間成CalendarDays的一個HashSet。

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; 
} 
上onCreateView(...)方法

,我已動態地設置所述兩個日曆日期,差異之間將被存儲在所述的HashSet。但是,您可以在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)); 

對我來說,BookingDecorator是實現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)); 

    } 
} 

您的帖子是非常有幫助的。希望我也幫助別人。

3

如果要更改選定的背景顏色編程,使用此方法: -

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

使用此代碼使相同顏色的所有選擇,所以如果你想有根據不同的顏色選擇你的條件,使用裝飾()