私の目標は、配列に基づいてカレンダービューでさまざまな日付をマークできるAndroidライブラリを見つけることです。日付は連続している場合と連続していない場合があります。私の理想的なシナリオは、各日付の背景色。重大な問題は、サーバークエリから取得されるため、実行時までこの色がわからないことです。
私はこれを一日中研究してきましたが、私の最高の希望は_material-calendarview
_( github )のようです。しかし、私は彼らのコードがやや侵入不可能であることに気づいています。それは私にありますが、私は完全に立ち往生しています。
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
_と呼ぶものに変換するという私の挑戦だと思います。同意しますか?しかし、これは私が本当に行き詰まっているところです。この データ構造 は私には奇妙です。 new CalendarDay()
を呼び出してインスタンス化しようとすると、クラスはすぐに約10個の新しいメソッドで展開されますが、それらの役割や処理方法がわかりません。明らかに、私はRailsここに行きます。これほどトリッキーになることはできません。
誰かがこの目的のためにこのライブラリを使用し、このタスクを実行する方法を知っていますか?私はひどく止まっています。また、実行時にのみ認識される色を使用して背景色を設定できる、より単純なライブラリがあれば、私はすべての耳です。
助けてくれてありがとう。私はこれを紛らわしい方法で書いたのではないかと心配しています。これは私が完全に混乱しているという事実の結果です。
選択した背景色をプログラムで変更する場合は、次の方法を使用します。-
MaterialCalendarView materialCalendar = (MaterialCalendarView)findViewById(R.id.materialCalenderView);
materialCalendar.setSelectionColor(Color.parseColor("#00BCD4"));
このコードを使用すると、すべてのセレクターが同じ色になるため、条件に応じて異なるカラーセレクターを使用する場合は、decorator()を使用します。
私はこれを解決したので、他の誰かが同じ質問をする場合に備えて、その解決策を投稿します。より効率的な方法がある場合は、解決策として投稿してください。
日付のリストを含む配列があると言いました。私がする必要があるのは、その配列を反復処理し、各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で苦労していたと述べたものに「変換」することです-a Collection<CalendarDay>
構造。ここに着いたら、これはこれ以上簡単なことではないことがわかりました。次のように割り当てるだけです。
calendarDays = list;
そして、デコレータを追加したいときは、すべて準備ができています。これを行うだけです:
calendarView.addDecorators(new EventDecorator(myColor, calendarDays));
もう1つ言及する必要があり、これが私の混乱の主な原因でした。これをインスタンス化する方法がわかりませんでした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;
}
};
これが誰かに役立つことを願っています。繰り返しますが、より良い解決策がある場合は、投稿してください。私のものを削除します。
HashSetの代わりにArrayListを使用したのはなぜですか?コレクションをインスタンス化できない理由は、コレクションがインターフェイスであるため、匿名クラスを作成してメソッドをオーバーライドする必要があったためです。
これが私が似たようなことをした方法です:
このメソッドは、2つのCalendarオブジェクトを受け取り、2つのCalendar日付の間のすべての日を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(...)メソッドで、2つのカレンダーの日付を動的に設定しましたが、その差は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));
}
}
あなたの投稿はとても役に立ちました。私が誰かを助けてくれることを願っています。