diff --git a/app/src/main/java/com/francesco/furlan/customizablecalendar/CalendarViewInteractor.java b/app/src/main/java/com/francesco/furlan/customizablecalendar/CalendarViewInteractor.java new file mode 100644 index 0000000..15fcd1f --- /dev/null +++ b/app/src/main/java/com/francesco/furlan/customizablecalendar/CalendarViewInteractor.java @@ -0,0 +1,119 @@ +package com.francesco.furlan.customizablecalendar; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.RelativeLayout; +import android.widget.TextView; + +import com.francesco.furlan.customizablecalendar.library.adapter.WeekDaysViewAdapter; +import com.francesco.furlan.customizablecalendar.library.interactors.ViewInteractor; +import com.francesco.furlan.customizablecalendar.library.model.Calendar; +import com.francesco.furlan.customizablecalendar.library.model.CalendarItem; + +import org.joda.time.DateTime; + +import java.util.List; + +/** + * Created by francescofurlan on 03/07/17. + */ + +public class CalendarViewInteractor implements ViewInteractor { + private Context context; + private Calendar calendar; + private TextView firstDaySelectedTxt; + private TextView lastDaySelectedTxt; + + CalendarViewInteractor(Context context) { + this.context = context; + } + + @Override + public void onCustomizableCalendarBindView(View view) { + + } + + @Override + public void onHeaderBindView(ViewGroup view) { + RelativeLayout layout = (RelativeLayout) LayoutInflater.from(context).inflate(R.layout.calendar_header, view); + firstDaySelectedTxt = (TextView) layout.findViewById(R.id.first_day_selected); + lastDaySelectedTxt = (TextView) layout.findViewById(R.id.last_day_selected); + updateCalendar(calendar); + } + + @Override + public void onWeekDaysBindView(View view) { + + } + + @Override + public void onWeekDayBindView(WeekDaysViewAdapter.WeekDayVH holder, String weekDay) { + + } + + @Override + public void onSubViewBindView(View view, String month) { + + } + + @Override + public void onCalendarBindView(View view) { + + } + + @Override + public void onMonthBindView(View view) { + + } + + @Override + public View onMonthCellBindView(View view, CalendarItem currentItem) { + return null; + } + + @Override + public boolean hasImplementedDayCalculation() { + return false; + } + + @Override + public List calculateDays(int year, int month, int firstDayOfMonth, int lastDayOfMonth) { + return null; + } + + @Override + public boolean hasImplementedSelection() { + return false; + } + + @Override + public int setSelected(boolean multipleSelection, DateTime dateSelected) { + return -1; + } + + @Override + public boolean hasImplementedMonthCellBinding() { + return false; + } + + @Override + public View getMonthGridView(View rootView) { + return null; + } + + void updateCalendar(Calendar calendar) { + this.calendar = calendar; + if (firstDaySelectedTxt != null && lastDaySelectedTxt != null) { + DateTime firstDate = calendar.getFirstSelectedDay(); + DateTime lastDate = calendar.getLastSelectedDay(); + if (firstDate != null) { + firstDaySelectedTxt.setText(firstDate.toString("dd MMMMM yyyy")); + } + if (lastDate != null) { + lastDaySelectedTxt.setText(lastDate.toString("dd MMMMM yyyy")); + } + } + } +} diff --git a/app/src/main/java/com/francesco/furlan/customizablecalendar/MainActivity.java b/app/src/main/java/com/francesco/furlan/customizablecalendar/MainActivity.java index 715b94b..47b442e 100644 --- a/app/src/main/java/com/francesco/furlan/customizablecalendar/MainActivity.java +++ b/app/src/main/java/com/francesco/furlan/customizablecalendar/MainActivity.java @@ -3,12 +3,63 @@ import android.os.Bundle; import android.support.v7.app.AppCompatActivity; +import com.francesco.furlan.customizablecalendar.library.components.CustomizableCalendar; +import com.francesco.furlan.customizablecalendar.library.interactors.AUCalendar; +import com.francesco.furlan.customizablecalendar.library.model.Calendar; + +import org.joda.time.DateTime; + +import butterknife.ButterKnife; +import butterknife.InjectView; +import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.functions.Consumer; + public class MainActivity extends AppCompatActivity { + @InjectView(R.id.view_month) + CustomizableCalendar customizableCalendar; + + private CompositeDisposable subscriptions; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); + ButterKnife.inject(this); + subscriptions = new CompositeDisposable(); + updateData(); } -} + private void updateData() { + // setting up first and last month that must be showed in the calendar + DateTime firstMonth = new DateTime().withDayOfMonth(1); + DateTime lastMonth = new DateTime().plusMonths(3).withDayOfMonth(1); + + // create the Calendar obj and setting it up with some configs like: + // - first selected day + // - last selected day + // - multiple selection + final Calendar calendar = new Calendar(firstMonth, lastMonth); + calendar.setFirstSelectedDay(new DateTime().plusDays(4)); + calendar.setLastSelectedDay(new DateTime().plusDays(6)); + calendar.setMultipleSelection(true); + + // create a CalendarViewInteractor obj needed to interact with the CustomizableCalendar + final CalendarViewInteractor calendarViewInteractor = new CalendarViewInteractor(getBaseContext()); + + // create the AUCalendar obj and observes changes on it + AUCalendar auCalendar = AUCalendar.getInstance(calendar); + calendarViewInteractor.updateCalendar(calendar); + subscriptions.add( + auCalendar.observeChangesOnCalendar().subscribe(new Consumer() { + @Override + public void accept(AUCalendar.ChangeSet changeSet) throws Exception { + calendarViewInteractor.updateCalendar(calendar); + } + }) + ); + + // inject (set) the calendarViewInteractor to the CustomizableCalendar + customizableCalendar.injectViewInteractor(calendarViewInteractor); + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 0d9cf32..88f0aae 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,7 +1,14 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/c_calendar.xml b/app/src/main/res/layout/c_calendar.xml new file mode 100644 index 0000000..aaf1fa0 --- /dev/null +++ b/app/src/main/res/layout/c_calendar.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/calendar_header.xml b/app/src/main/res/layout/calendar_header.xml new file mode 100644 index 0000000..170627b --- /dev/null +++ b/app/src/main/res/layout/calendar_header.xml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index db8b5b0..153df77 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,3 +1,6 @@ CustomizableCalendar + day month year + First day selected + Last day selected diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..5885930 --- /dev/null +++ b/app/src/main/res/values/styles.xml @@ -0,0 +1,11 @@ + + + + + + diff --git a/library/.gitignore b/library/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/library/.gitignore @@ -0,0 +1 @@ +/build diff --git a/library/build.gradle b/library/build.gradle index df0502b..59c9909 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -1,4 +1,5 @@ apply plugin: 'com.android.library' +apply plugin: 'me.tatarka.retrolambda' android { compileSdkVersion 25 @@ -19,6 +20,10 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } } dependencies { @@ -27,5 +32,14 @@ dependencies { exclude group: 'com.android.support', module: 'support-annotations' }) compile 'com.android.support:appcompat-v7:25.3.1' + compile 'com.android.support:recyclerview-v7:25.3.1' testCompile 'junit:junit:4.12' + compile 'joda-time:joda-time:2.9.9' + compile 'com.jakewharton:butterknife:6.1.0' + compile "io.reactivex.rxjava2:rxjava:2.0.1" + retrolambdaConfig 'net.orfjackal.retrolambda:retrolambda:2.5.1' +} + +retrolambda { + javaVersion JavaVersion.VERSION_1_7 } \ No newline at end of file diff --git a/library/src/main/java/com/francesco/furlan/customizablecalendar/library/adapter/CalendarViewAdapter.java b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/adapter/CalendarViewAdapter.java new file mode 100644 index 0000000..a0408ff --- /dev/null +++ b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/adapter/CalendarViewAdapter.java @@ -0,0 +1,97 @@ +package com.francesco.furlan.customizablecalendar.library.adapter; + +import android.content.Context; +import android.support.annotation.LayoutRes; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.LinearLayout; + +import com.francesco.furlan.customizablecalendar.library.R; +import com.francesco.furlan.customizablecalendar.library.components.MonthGridView; +import com.francesco.furlan.customizablecalendar.library.interactors.AUCalendar; +import com.francesco.furlan.customizablecalendar.library.interactors.ViewInteractor; +import com.francesco.furlan.customizablecalendar.library.presenter.interfeaces.CustomizableCalendarPresenter; +import com.francesco.furlan.customizablecalendar.library.view.BaseView; + +/** + * Created by francescofurlan on 23/06/17. + */ + +public class CalendarViewAdapter extends RecyclerView.Adapter implements BaseView { + private Context context; + private AUCalendar calendar; + private int layoutResId = -1; + private int dayLayoutResId = -1; + private ViewInteractor viewInteractor; + + public CalendarViewAdapter(Context context) { + this.context = context; + this.calendar = AUCalendar.getInstance(); + } + + @Override + public int getItemCount() { + return calendar.getMonths().size(); + } + + @Override + public CalendarViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { + View rootView; + if (layoutResId != -1 && layoutResId != R.layout.calendar_view) { + rootView = LayoutInflater.from(context).inflate(layoutResId, null); + rootView = viewInteractor.getMonthGridView(rootView); + } else { + MonthGridView monthGridView = new MonthGridView(context); + LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); + monthGridView.setLayoutParams(params); + rootView = monthGridView; + } + + if (viewInteractor != null) { + viewInteractor.onMonthBindView(rootView); + } + return new CalendarViewHolder(rootView, layoutResId, dayLayoutResId, viewInteractor); + } + + @Override + public void onBindViewHolder(final CalendarViewHolder viewHolder, final int position) { + viewHolder.monthView.refreshData(); + } + + @Override + public void refreshData() { + notifyDataSetChanged(); + } + + @Override + public void setLayoutResId(@LayoutRes int layoutResId) { + this.layoutResId = layoutResId; + } + + public void setDayLayoutResId(@LayoutRes int layoutResId) { + this.dayLayoutResId = layoutResId; + } + + @Override + public void injectViewInteractor(ViewInteractor viewInteractor) { + this.viewInteractor = viewInteractor; + } + + @Override + public void injectPresenter(CustomizableCalendarPresenter presenter) { + } + + static class CalendarViewHolder extends RecyclerView.ViewHolder { + MonthGridView monthView; + + CalendarViewHolder(View view, int layoutResId, int dayLayoutResId, ViewInteractor viewInteractor) { + super(view); + monthView = (MonthGridView) view; + monthView.setLayoutResId(layoutResId); + monthView.setDayLayoutResId(dayLayoutResId); + monthView.injectViewInteractor(viewInteractor); + } + } +} \ No newline at end of file diff --git a/library/src/main/java/com/francesco/furlan/customizablecalendar/library/adapter/MonthAdapter.java b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/adapter/MonthAdapter.java new file mode 100644 index 0000000..1b4c1ab --- /dev/null +++ b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/adapter/MonthAdapter.java @@ -0,0 +1,299 @@ +package com.francesco.furlan.customizablecalendar.library.adapter; + +import android.content.Context; +import android.graphics.Color; +import android.support.annotation.LayoutRes; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.TextView; + +import com.francesco.furlan.customizablecalendar.library.R; +import com.francesco.furlan.customizablecalendar.library.interactors.AUCalendar; +import com.francesco.furlan.customizablecalendar.library.interactors.ViewInteractor; +import com.francesco.furlan.customizablecalendar.library.model.CalendarFields; +import com.francesco.furlan.customizablecalendar.library.model.CalendarItem; +import com.francesco.furlan.customizablecalendar.library.presenter.interfeaces.CustomizableCalendarPresenter; +import com.francesco.furlan.customizablecalendar.library.utils.DateUtils; +import com.francesco.furlan.customizablecalendar.library.view.MonthView; + +import org.joda.time.DateTime; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +import io.reactivex.disposables.CompositeDisposable; + +/** + * Created by francescofurlan on 23/06/17. + */ + +public class MonthAdapter extends BaseAdapter implements MonthView { + private Context context; + private AUCalendar calendar; + private int layoutResId; + private List days; + private ViewInteractor viewInteractor; + + private DateTime currentMonth; + private DateTime firstSelectedDay; + private DateTime lastSelectedDay; + private boolean multipleSelection; + private int firstDayOfWeek; + + private CompositeDisposable subscriptions; + + public MonthAdapter(Context context) { + this.context = context; + this.subscriptions = new CompositeDisposable(); + this.calendar = AUCalendar.getInstance(); + this.layoutResId = R.layout.calendar_cell; + initFromCalendar(); + subscribe(); + } + + private void initFromCalendar() { + currentMonth = calendar.getCurrentMonth().withDayOfMonth(1).withMillisOfDay(0); + + firstSelectedDay = calendar.getFirstSelectedDay(); + if (firstSelectedDay != null) { + firstSelectedDay = firstSelectedDay.withMillisOfDay(0); + } + lastSelectedDay = calendar.getLastSelectedDay(); + if (lastSelectedDay != null) { + lastSelectedDay = lastSelectedDay.withMillisOfDay(0); + } + multipleSelection = calendar.isMultipleSelectionEnabled(); + firstDayOfWeek = calendar.getFirstDayOfWeek(); + } + + @Override + public int getCount() { + return days.size(); + } + + @Override + public Object getItem(int position) { + return days.get(position); + } + + @Override + public long getItemId(int position) { + final CalendarItem item = days.get(position); + if (item != null) { + return days.get(position).getId(); + } + return -1; + } + + @Override + public View getView(int position, View view, ViewGroup parent) { + final CalendarItem currentItem = days.get(position); + + if (view == null) { + LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + view = inflater.inflate(layoutResId, null); + } + + if (viewInteractor != null && viewInteractor.hasImplementedMonthCellBinding()) { + view = viewInteractor.onMonthCellBindView(view, currentItem); + } else { + final TextView dayView = (TextView) view.findViewById(android.R.id.title); + final View background = view.findViewById(android.R.id.background); + final View startSelectionView = view.findViewById(android.R.id.startSelectingText); + final View endSelectionView = view.findViewById(android.R.id.stopSelectingText); + + startSelectionView.setVisibility(View.GONE); + endSelectionView.setVisibility(View.GONE); + + if (currentItem == null) { + background.setBackground(null); + dayView.setText(null); + } else if (currentItem.compareTo(calendar.getFirstMonth().withMillisOfDay(0)) < 0) { + currentItem.setSelectable(false); + background.setBackground(null); + dayView.setTextColor(Color.BLACK); + dayView.setText(currentItem.getDayString()); + dayView.setAlpha(0.6f); + } else { + currentItem.setSelectable(true); + dayView.setAlpha(1f); + Integer backgroundResource = null; + if (firstSelectedDay != null) { + int startSelectedCompared = currentItem.compareTo(firstSelectedDay); + if (!multipleSelection) { + if (startSelectedCompared == 0) { + backgroundResource = R.drawable.empty_circle; + } + } else if (startSelectedCompared == 0) { + if (lastSelectedDay == null || lastSelectedDay.equals(currentItem.getDateTime())) { + backgroundResource = R.drawable.circle; + } else { + backgroundResource = R.drawable.left_rounded_rectangle; + endSelectionView.setVisibility(View.VISIBLE); + } + } else if (startSelectedCompared > 0 && lastSelectedDay != null) { + int endSelectedCompared = currentItem.compareTo(lastSelectedDay); + if (endSelectedCompared == 0) { + backgroundResource = R.drawable.right_rounded_rectangle; + startSelectionView.setVisibility(View.VISIBLE); + } else if (endSelectedCompared < 0) { + backgroundResource = R.drawable.rectangle; + startSelectionView.setVisibility(View.VISIBLE); + endSelectionView.setVisibility(View.VISIBLE); + } + } + } + + int color = Color.BLACK; + if (backgroundResource != null) { + background.setBackgroundResource(backgroundResource); + if (multipleSelection) { + color = Color.WHITE; + } + } else { + background.setBackground(null); + } + + dayView.setTextColor(color); + dayView.setText(currentItem.getDayString()); + } + } + + return view; + } + + @Override + public void refreshData() { + refreshDays(); + } + + @Override + public void setLayoutResId(@LayoutRes int layoutResId) { + if (layoutResId != -1) { + this.layoutResId = layoutResId; + } + } + + @Override + public void injectViewInteractor(ViewInteractor viewInteractor) { + this.viewInteractor = viewInteractor; + } + + @Override + public void injectPresenter(CustomizableCalendarPresenter presenter) { + } + + /** + * Select the day specified if multiple selection mode is not enabled, + * otherwise adjust the ends of the selection: + * first end will be set if the day specified is before the first end; + * last end will be set if the day specified is after the last end; + * + * @param dateSelected a DateTime object that represents the day that + * should be selected + */ + @Override + public void setSelected(DateTime dateSelected) { + if (viewInteractor != null && viewInteractor.hasImplementedSelection()) { + int itemSelected = viewInteractor.setSelected(multipleSelection, dateSelected); + switch (itemSelected) { + case 0: + notifyFirstSelectionUpdated(dateSelected); + break; + case 1: + notifyLastSelectionUpdated(dateSelected); + break; + default: + return; + } + } else { + if (!multipleSelection) { + notifyFirstSelectionUpdated(dateSelected); + } else { + if (firstSelectedDay != null) { + int startSelectedCompared = dateSelected.compareTo(firstSelectedDay); + if (startSelectedCompared < 0) { + notifyFirstSelectionUpdated(dateSelected); + } else if (lastSelectedDay != null) { + int endSelectedCompared = dateSelected.compareTo(lastSelectedDay); + if ((startSelectedCompared >= 0 && endSelectedCompared < 0) || endSelectedCompared > 0) { + notifyLastSelectionUpdated(dateSelected); + } + } else { + notifyLastSelectionUpdated(dateSelected); + } + } else { + notifyFirstSelectionUpdated(dateSelected); + } + } + } + notifyDataSetChanged(); + } + + private void notifyFirstSelectionUpdated(DateTime startSelected) { + this.firstSelectedDay = startSelected; + this.calendar.setFirstSelectedDay(startSelected); + } + + private void notifyLastSelectionUpdated(DateTime endSelected) { + this.lastSelectedDay = endSelected; + this.calendar.setLastSelectedDay(endSelected); + } + + @Override + public final void refreshDays() { + final int empties; + final int year = currentMonth.getYear(); + final int month = currentMonth.getMonthOfYear(); + final int firstDayOfMonth = currentMonth.getDayOfWeek() + 1; + final int lastDayOfMonth = DateUtils.getDaysInMonth(month - 1, year); + + if (viewInteractor != null && viewInteractor.hasImplementedDayCalculation()) { + days = viewInteractor.calculateDays(year, month, firstDayOfMonth, lastDayOfMonth); + } else { + // default days calculation + if (firstDayOfMonth == firstDayOfWeek) { + empties = 0; + } else if (firstDayOfMonth < firstDayOfWeek) { + empties = Calendar.SATURDAY - (firstDayOfWeek - 1); + } else { + empties = firstDayOfMonth - firstDayOfWeek; + } + + int totDays = lastDayOfMonth + empties; + days = new ArrayList<>(totDays); + + for (int day = 1, position = 1; position < totDays; position++) { + if (position > empties) { + days.add(new CalendarItem(day++, month, year)); + } else { + days.add(null); + } + } + } + + notifyDataSetChanged(); + } + + private void subscribe() { + subscriptions.add( + calendar.observeChangesOnCalendar() + .subscribe(changeSet -> { + if (changeSet.isFieldChanged(CalendarFields.FIRST_DAY_OF_WEEK) + || changeSet.isFieldChanged(CalendarFields.FIRST_SELECTED_DAY) + || changeSet.isFieldChanged(CalendarFields.LAST_SELECTED_DAY)) { + initFromCalendar(); + refreshDays(); + } + }) + ); + } + + @Override + public void unsubscribe() { + subscriptions.clear(); + } +} \ No newline at end of file diff --git a/library/src/main/java/com/francesco/furlan/customizablecalendar/library/adapter/WeekDaysViewAdapter.java b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/adapter/WeekDaysViewAdapter.java new file mode 100644 index 0000000..6e0e4e8 --- /dev/null +++ b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/adapter/WeekDaysViewAdapter.java @@ -0,0 +1,82 @@ +package com.francesco.furlan.customizablecalendar.library.adapter; + +import android.content.Context; +import android.support.annotation.LayoutRes; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import com.francesco.furlan.customizablecalendar.library.interactors.ViewInteractor; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by francescofurlan on 28/06/17. + */ + +public class WeekDaysViewAdapter extends RecyclerView.Adapter { + + private Context context; + private List weekDays = new ArrayList<>(); + private ItemClickListener clickListener; + private ViewInteractor viewInteractor; + private @LayoutRes int layoutResId; + + public WeekDaysViewAdapter(Context context, List weekDays, @LayoutRes int layoutResId, ViewInteractor viewInteractor) { + this.context = context; + this.weekDays = weekDays; + this.layoutResId = layoutResId; + this.viewInteractor = viewInteractor; + } + + @Override + public WeekDayVH onCreateViewHolder(ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(layoutResId, parent, false); + return new WeekDayVH(view); + } + + @Override + public void onBindViewHolder(WeekDayVH holder, int position) { + String weekDay = getItem(position); + holder.weekDayTxt.setText(weekDay); + viewInteractor.onWeekDayBindView(holder, weekDay); + } + + @Override + public int getItemCount() { + return weekDays.size(); + } + + public String getItem(int position) { + return weekDays.get(position); + } + + public void setClickListener(ItemClickListener clickListener) { + this.clickListener = clickListener; + } + + public interface ItemClickListener { + void onItemClick(View view, int position); + } + + public class WeekDayVH extends RecyclerView.ViewHolder implements View.OnClickListener { + TextView weekDayTxt; + + public WeekDayVH(View itemView) { + super(itemView); + weekDayTxt = (TextView) itemView.findViewById(android.R.id.summary); + itemView.setOnClickListener(this); + } + + @Override + public void onClick(View view) { + if (clickListener != null) { + clickListener.onItemClick(view, getAdapterPosition()); + } + } + } +} + diff --git a/library/src/main/java/com/francesco/furlan/customizablecalendar/library/components/CalendarRecyclerView.java b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/components/CalendarRecyclerView.java new file mode 100644 index 0000000..ef3a8c6 --- /dev/null +++ b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/components/CalendarRecyclerView.java @@ -0,0 +1,147 @@ +package com.francesco.furlan.customizablecalendar.library.components; + +import android.content.Context; +import android.content.res.TypedArray; +import android.support.annotation.LayoutRes; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.PagerSnapHelper; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.SnapHelper; +import android.util.AttributeSet; +import android.view.View; + +import com.francesco.furlan.customizablecalendar.library.R; +import com.francesco.furlan.customizablecalendar.library.adapter.CalendarViewAdapter; +import com.francesco.furlan.customizablecalendar.library.interactors.AUCalendar; +import com.francesco.furlan.customizablecalendar.library.interactors.ViewInteractor; +import com.francesco.furlan.customizablecalendar.library.presenter.interfeaces.CustomizableCalendarPresenter; +import com.francesco.furlan.customizablecalendar.library.view.CalendarView; + +import org.joda.time.DateTime; + +/** + * Created by francescofurlan on 23/06/17. + */ + +public class CalendarRecyclerView extends RecyclerView implements CalendarView { + private LinearLayoutManager linearLayoutManager; + private CalendarViewAdapter calendarViewAdapter; + private ViewInteractor viewInteractor; + private Context context; + private CustomizableCalendarPresenter presenter; + private int currentPosition = 0; + private int prevPosition = 0; + private int detachPosition = 0; + private AUCalendar calendar; + private + @LayoutRes + int monthResId = R.layout.calendar_view; + private + @LayoutRes + int monthCellResId = R.layout.calendar_cell; + + public CalendarRecyclerView(Context context) { + this(context, null); + } + + public CalendarRecyclerView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public CalendarRecyclerView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(context, attrs); + } + + private void init(Context context, AttributeSet attrs) { + this.context = context; + + TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomizableCalendar); + if (typedArray != null) { + monthResId = typedArray.getResourceId(R.styleable.CustomizableCalendar_month_layout, R.layout.calendar_view); + monthCellResId = typedArray.getResourceId(R.styleable.CustomizableCalendar_cell_layout, R.layout.calendar_cell); + typedArray.recycle(); + } + + linearLayoutManager = new LinearLayoutManager(getContext()); + linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); + setLayoutManager(linearLayoutManager); + this.calendar = AUCalendar.getInstance(); + } + + @Override + public void refreshData() { + calendarViewAdapter.refreshData(); + } + + @Override + public void setLayoutResId(@LayoutRes int layoutResId) { + + } + + @Override + public void injectViewInteractor(ViewInteractor viewInteractor) { + this.viewInteractor = viewInteractor; + if (viewInteractor != null) { + viewInteractor.onCalendarBindView(this); + } + setupCalendarAdapter(); + setupCalendarScroll(); + } + + @Override + public void injectPresenter(CustomizableCalendarPresenter presenter) { + this.presenter = presenter; + this.presenter.injectCalendarView(this); + } + + private void setupCalendarAdapter() { + calendarViewAdapter = new CalendarViewAdapter(context); + calendarViewAdapter.injectViewInteractor(viewInteractor); + calendarViewAdapter.setLayoutResId(monthResId); + calendarViewAdapter.setDayLayoutResId(monthCellResId); + setAdapter(calendarViewAdapter); + } + + private void setupCalendarScroll() { + SnapHelper snapHelper = new PagerSnapHelper(); + snapHelper.attachToRecyclerView(this); + + addOnChildAttachStateChangeListener(new RecyclerView.OnChildAttachStateChangeListener() { + @Override + public void onChildViewAttachedToWindow(View view) { + prevPosition = currentPosition; + currentPosition = getChildAdapterPosition(view); + updateCurrentMonth(); + MonthGridView monthGridView = (MonthGridView) view; + monthGridView.refreshData(); + } + + @Override + public void onChildViewDetachedFromWindow(View view) { + MonthGridView monthGridView = (MonthGridView) view; + detachPosition = getChildAdapterPosition(view); + if (detachPosition == currentPosition) { + currentPosition = prevPosition; + updateCurrentMonth(); + } + monthGridView.unsubscribe(); + } + }); + } + + private void updateCurrentMonth() { + DateTime currentMonth = calendar.getMonths().get(currentPosition); + calendar.setCurrentMonth(currentMonth); + } + + @Override + public void setMonthLayoutResId(@LayoutRes int layoutResId) { + calendarViewAdapter.setLayoutResId(layoutResId); + } + + @Override + public void setDayLayoutResId(@LayoutRes int layoutResId) { + calendarViewAdapter.setDayLayoutResId(layoutResId); + } +} \ No newline at end of file diff --git a/library/src/main/java/com/francesco/furlan/customizablecalendar/library/components/CustomizableCalendar.java b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/components/CustomizableCalendar.java new file mode 100644 index 0000000..dd5811d --- /dev/null +++ b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/components/CustomizableCalendar.java @@ -0,0 +1,104 @@ +package com.francesco.furlan.customizablecalendar.library.components; + +import android.content.Context; +import android.content.res.TypedArray; +import android.support.annotation.Nullable; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.widget.LinearLayout; + +import com.francesco.furlan.customizablecalendar.library.R; +import com.francesco.furlan.customizablecalendar.library.interactors.ViewInteractor; +import com.francesco.furlan.customizablecalendar.library.presenter.implementations.CustomizableCalendarPresenterImpl; +import com.francesco.furlan.customizablecalendar.library.presenter.interfeaces.CustomizableCalendarPresenter; +import com.francesco.furlan.customizablecalendar.library.view.CustomizableCalendarView; + +import butterknife.ButterKnife; +import butterknife.InjectView; + +/** + * Created by francescofurlan on 23/06/17. + */ + +public class CustomizableCalendar extends LinearLayout implements CustomizableCalendarView { + + @InjectView(android.R.id.primary) + HeaderView headerView; + + @InjectView(android.R.id.text1) + WeekDaysView weekDaysView; + + @InjectView(android.R.id.text2) + SubView subView; + + @InjectView(android.R.id.content) + CalendarRecyclerView calendarRecyclerView; + + CustomizableCalendarPresenter presenter; + + private int layoutResId = -1; + + public CustomizableCalendar(Context context) { + this(context, null); + } + + public CustomizableCalendar(Context context, @Nullable AttributeSet attrs) { + this(context, attrs, 0); + } + + public CustomizableCalendar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(context, attrs, defStyleAttr); + } + + private void init(Context context, AttributeSet attrs, int defStyleAttr) { + if (presenter == null) { + TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomizableCalendar); + presenter = new CustomizableCalendarPresenterImpl(); + presenter.setView(this); + layoutResId = R.layout.customizable_calendar; + if (typedArray != null) { + layoutResId = typedArray.getResourceId(R.styleable.CustomizableCalendar_layout, R.layout.customizable_calendar); + typedArray.recycle(); + } + + LayoutInflater.from(context).inflate(layoutResId, this); + ButterKnife.inject(this); + } + } + + public CustomizableCalendarPresenter getPresenter() { + return presenter; + } + + @Override + public void injectViewInteractor(ViewInteractor viewInteractor) { + viewInteractor.onCustomizableCalendarBindView(this); + presenter.injectViewInteractor(viewInteractor); + headerView.injectPresenter(presenter); + calendarRecyclerView.injectPresenter(presenter); + subView.injectPresenter(presenter); + weekDaysView.injectPresenter(presenter); + } + + @Override + public void injectPresenter(CustomizableCalendarPresenter presenter) { + this.presenter = presenter; + presenter.setView(this); + } + + @Override + public void onCurrentMonthChanged(String month) { + subView.onMonthChanged(month); + } + + @Override + public void refreshData() { + + } + + @Override + public void setLayoutResId(int layoutResId) { + this.layoutResId = layoutResId; + } +} \ No newline at end of file diff --git a/library/src/main/java/com/francesco/furlan/customizablecalendar/library/components/HeaderView.java b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/components/HeaderView.java new file mode 100644 index 0000000..a1dc3eb --- /dev/null +++ b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/components/HeaderView.java @@ -0,0 +1,61 @@ +package com.francesco.furlan.customizablecalendar.library.components; + +import android.content.Context; +import android.support.annotation.LayoutRes; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.widget.RelativeLayout; + +import com.francesco.furlan.customizablecalendar.library.interactors.ViewInteractor; +import com.francesco.furlan.customizablecalendar.library.presenter.interfeaces.CustomizableCalendarPresenter; + +/** + * Created by francescofurlan on 23/06/17. + */ + +public class HeaderView extends RelativeLayout implements com.francesco.furlan.customizablecalendar.library.view.HeaderView { + private CustomizableCalendarPresenter presenter; + private ViewInteractor viewInteractor; + private Context context; + + public HeaderView(Context context) { + this(context, null); + } + + public HeaderView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public HeaderView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(context); + } + + private void init(Context context) { + this.context = context; + } + + @Override + public void refreshData() { + + } + + @Override + public void setLayoutResId(@LayoutRes int layoutResId) { + if (layoutResId != -1) { + LayoutInflater.from(context).inflate(layoutResId, this); + } + } + + @Override + public void injectViewInteractor(ViewInteractor viewInteractor) { + this.viewInteractor = viewInteractor; + this.viewInteractor.onHeaderBindView(this); + } + + @Override + public void injectPresenter(CustomizableCalendarPresenter presenter) { + this.presenter = presenter; + this.presenter.injectHeaderView(this); + } +} \ No newline at end of file diff --git a/library/src/main/java/com/francesco/furlan/customizablecalendar/library/components/MonthGridView.java b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/components/MonthGridView.java new file mode 100644 index 0000000..5b3d5da --- /dev/null +++ b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/components/MonthGridView.java @@ -0,0 +1,126 @@ +package com.francesco.furlan.customizablecalendar.library.components; + +import android.content.Context; +import android.content.res.TypedArray; +import android.support.annotation.LayoutRes; +import android.support.annotation.Nullable; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.widget.GridView; +import android.widget.LinearLayout; + +import com.francesco.furlan.customizablecalendar.library.R; +import com.francesco.furlan.customizablecalendar.library.adapter.MonthAdapter; +import com.francesco.furlan.customizablecalendar.library.interactors.ViewInteractor; +import com.francesco.furlan.customizablecalendar.library.model.CalendarItem; +import com.francesco.furlan.customizablecalendar.library.presenter.interfeaces.CustomizableCalendarPresenter; +import com.francesco.furlan.customizablecalendar.library.view.BaseView; + +import org.joda.time.DateTime; + +/** + * Created by francescofurlan on 23/06/17. + */ + +public class MonthGridView extends LinearLayout implements BaseView { + protected DateTime monthDateTime; + private MonthAdapter calendarAdapter; + private GridView calendarGrid; + private LinearLayout calendarLayout; + private + @LayoutRes + int layoutResId = -1; + private + @LayoutRes + int dayLayoutResId = -1; + private ViewInteractor viewInteractor; + + public MonthGridView(Context context) { + this(context, null); + } + + public MonthGridView(Context context, @Nullable AttributeSet attrs) { + this(context, attrs, 0); + } + + public MonthGridView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(context, attrs); + } + + private void init(Context context, AttributeSet attrs) { + monthDateTime = new DateTime(); + layoutResId = R.layout.calendar_view; + + TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomizableCalendar); + if (typedArray != null) { + layoutResId = typedArray.getResourceId(R.styleable.CustomizableCalendar_month_layout, R.layout.calendar_view); + dayLayoutResId = typedArray.getResourceId(R.styleable.CustomizableCalendar_cell_layout, R.layout.calendar_cell); + typedArray.recycle(); + } + + } + + @Override + public void setLayoutResId(@LayoutRes int layoutResId) { + if (layoutResId != -1) { + this.layoutResId = layoutResId; + } + } + + public void setDayLayoutResId(int dayLayoutResId) { + if (layoutResId != -1) { + this.dayLayoutResId = dayLayoutResId; + } + } + + @Override + public void injectViewInteractor(ViewInteractor viewInteractor) { + this.viewInteractor = viewInteractor; + bindViews(); + setupCalendar(); + } + + @Override + public void injectPresenter(CustomizableCalendarPresenter presenter) { + + } + + private void bindViews() { + calendarLayout = (LinearLayout) LayoutInflater.from(getContext()).inflate(layoutResId, this); + calendarGrid = (GridView) calendarLayout.findViewById(android.R.id.widget_frame); + } + + private void setupCalendar() { + calendarAdapter = new MonthAdapter(getContext()); + + calendarAdapter.setLayoutResId(dayLayoutResId); + + calendarAdapter.injectViewInteractor(viewInteractor); + + calendarAdapter.refreshDays(); + + calendarGrid.setAdapter(calendarAdapter); + + calendarGrid.setOnItemClickListener((parent, view, position, id) -> { + Object currentObj = calendarAdapter.getItem(position); + if (currentObj != null) { + CalendarItem calendarItem = (CalendarItem) currentObj; + if (calendarItem.isSelectable()) { + calendarAdapter.setSelected(calendarItem.getDateTime()); + } + } + }); + } + + @Override + public void refreshData() { + setupCalendar(); + } + + public void unsubscribe() { + if (calendarAdapter != null) { + calendarAdapter.unsubscribe(); + } + } +} \ No newline at end of file diff --git a/library/src/main/java/com/francesco/furlan/customizablecalendar/library/components/SubView.java b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/components/SubView.java new file mode 100644 index 0000000..aa4a0a2 --- /dev/null +++ b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/components/SubView.java @@ -0,0 +1,96 @@ +package com.francesco.furlan.customizablecalendar.library.components; + +import android.content.Context; +import android.content.res.TypedArray; +import android.support.annotation.LayoutRes; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.widget.RelativeLayout; +import android.widget.TextView; + +import com.francesco.furlan.customizablecalendar.library.R; +import com.francesco.furlan.customizablecalendar.library.interactors.AUCalendar; +import com.francesco.furlan.customizablecalendar.library.interactors.ViewInteractor; +import com.francesco.furlan.customizablecalendar.library.presenter.interfeaces.CustomizableCalendarPresenter; + +import org.joda.time.DateTime; + +import java.util.Locale; + +import butterknife.ButterKnife; +import butterknife.InjectView; + +/** + * Created by francescofurlan on 23/06/17. + */ + +public class SubView extends RelativeLayout implements com.francesco.furlan.customizablecalendar.library.view.SubView { + @InjectView(android.R.id.message) + TextView monthTxt; + + private ViewInteractor viewInteractor; + + private @LayoutRes int layoutResId = R.layout.sub_view; + private CustomizableCalendarPresenter presenter; + private Context context; + + public SubView(Context context) { + this(context, null); + } + + public SubView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public SubView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(context, attrs); + } + + private void init(Context context, AttributeSet attrs) { + this.context = context; + TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomizableCalendar); + if (typedArray != null) { + layoutResId = typedArray.getResourceId(R.styleable.CustomizableCalendar_layout, R.layout.sub_view); + typedArray.recycle(); + } + + LayoutInflater.from(context).inflate(layoutResId, this); + ButterKnife.inject(this); + } + + @Override + public void onMonthChanged(String month) { + monthTxt.setText(month); + if (viewInteractor != null) { + viewInteractor.onSubViewBindView(this, month); + } + } + + @Override + public void refreshData() { + } + + @Override + public void setLayoutResId(@LayoutRes int layoutResId) { + this.layoutResId = layoutResId; + } + + @Override + public void injectViewInteractor(ViewInteractor viewInteractor) { + this.viewInteractor = viewInteractor; + DateTime firstMonth = AUCalendar.getInstance().getFirstMonth(); + String month = firstMonth.toString("MMMMM", Locale.getDefault()); + if (!TextUtils.isEmpty(month)) { + String formattedMonth = month.substring(0, 1).toUpperCase() + month.substring(1); + onMonthChanged(formattedMonth); + } + } + + @Override + public void injectPresenter(CustomizableCalendarPresenter presenter) { + this.presenter = presenter; + this.presenter.injectSubView(this); + } +} \ No newline at end of file diff --git a/library/src/main/java/com/francesco/furlan/customizablecalendar/library/components/WeekDaysView.java b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/components/WeekDaysView.java new file mode 100644 index 0000000..4694583 --- /dev/null +++ b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/components/WeekDaysView.java @@ -0,0 +1,123 @@ +package com.francesco.furlan.customizablecalendar.library.components; + +import android.content.Context; +import android.content.res.TypedArray; +import android.support.annotation.LayoutRes; +import android.support.annotation.Nullable; +import android.support.v7.widget.GridLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.text.TextUtils; +import android.util.AttributeSet; + +import com.francesco.furlan.customizablecalendar.library.R; +import com.francesco.furlan.customizablecalendar.library.adapter.WeekDaysViewAdapter; +import com.francesco.furlan.customizablecalendar.library.interactors.AUCalendar; +import com.francesco.furlan.customizablecalendar.library.interactors.ViewInteractor; +import com.francesco.furlan.customizablecalendar.library.presenter.interfeaces.CustomizableCalendarPresenter; + +import java.text.DateFormatSymbols; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +/** + * Created by francescofurlan on 23/06/17. + */ + +public class WeekDaysView extends RecyclerView implements com.francesco.furlan.customizablecalendar.library.view.WeekDaysView { + WeekDaysViewAdapter weekDaysViewAdapter; + private Context context; + private @LayoutRes int layoutResId = -1; + private ViewInteractor viewInteractor; + private Integer firstDayOfWeek; + private CustomizableCalendarPresenter presenter; + + public WeekDaysView(Context context) { + this(context, null); + } + + public WeekDaysView(Context context, @Nullable AttributeSet attrs) { + this(context, attrs, 0); + } + + public WeekDaysView(Context context, @Nullable AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(context, attrs); + } + + private void init(Context context, AttributeSet attrs) { + this.context = context; + TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomizableCalendar); + layoutResId = R.layout.week_day_view; + if (typedArray != null) { + layoutResId = typedArray.getResourceId(R.styleable.CustomizableCalendar_layout, R.layout.week_day_view); + typedArray.recycle(); + } + } + + private String getFormattedDayOfDay(String nameOfDay) { + if (!TextUtils.isEmpty(nameOfDay)) { + return nameOfDay.substring(0, 1).toUpperCase(); + } + return null; + } + + public void setWeekDays(List weekDays) { + weekDaysViewAdapter = new WeekDaysViewAdapter(context, weekDays, layoutResId, viewInteractor); + setAdapter(weekDaysViewAdapter); + setLayoutManager(new GridLayoutManager(context, weekDays.size())); + } + + @Override + public void refreshData() { + + } + + @Override + public void setLayoutResId(@LayoutRes int layoutResId) { + this.layoutResId = layoutResId; + } + + @Override + public void injectViewInteractor(ViewInteractor viewInteractor) { + this.viewInteractor = viewInteractor; + setupWeekDays(); + } + + @Override + public void injectPresenter(CustomizableCalendarPresenter presenter) { + this.presenter = presenter; + presenter.injectWeekDaysView(this); + } + + @Override + public void onFirstDayOfWeek(int firstDayOfWeek) { + this.firstDayOfWeek = firstDayOfWeek; + setupWeekDays(); + } + + private void setupWeekDays() { + viewInteractor.onWeekDaysBindView(this); + String[] namesOfDays = DateFormatSymbols.getInstance(Locale.getDefault()).getShortWeekdays(); + if (firstDayOfWeek == null) { + firstDayOfWeek = AUCalendar.getInstance().getFirstDayOfWeek(); + } + + List weekDays = new ArrayList<>(); + for (int i = firstDayOfWeek; i < namesOfDays.length; i++) { + String nameOfDay = namesOfDays[i]; + String formattedNameOfDay = getFormattedDayOfDay(nameOfDay); + if (formattedNameOfDay != null) { + weekDays.add(formattedNameOfDay); + } + } + for (int i = 0; i < firstDayOfWeek; i++) { + String nameOfDay = namesOfDays[i]; + String formattedNameOfDay = getFormattedDayOfDay(nameOfDay); + if (formattedNameOfDay != null) { + weekDays.add(formattedNameOfDay); + } + } + setWeekDays(weekDays); + } +} diff --git a/library/src/main/java/com/francesco/furlan/customizablecalendar/library/interactors/AUCalendar.java b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/interactors/AUCalendar.java new file mode 100644 index 0000000..1143a03 --- /dev/null +++ b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/interactors/AUCalendar.java @@ -0,0 +1,187 @@ +package com.francesco.furlan.customizablecalendar.library.interactors; + +import com.francesco.furlan.customizablecalendar.library.model.Calendar; +import com.francesco.furlan.customizablecalendar.library.model.CalendarFields; + +import org.joda.time.DateTime; + +import java.util.ArrayList; +import java.util.List; + +import io.reactivex.BackpressureStrategy; +import io.reactivex.Flowable; +import io.reactivex.FlowableEmitter; + +/** + * Created by francescofurlan on 30/06/17. + */ + +public class AUCalendar { + private static AUCalendar AUCalendarInstance; + private Calendar calendar; + private List onChangeListenerList = new ArrayList<>(); + + public static AUCalendar getInstance() { + if (AUCalendarInstance == null) { + AUCalendarInstance = new AUCalendar(); + } + return AUCalendarInstance; + } + + public static AUCalendar getInstance(Calendar calendar) { + getInstance(); + if (calendar != null) { + AUCalendarInstance.setCalendar(calendar); + } + return AUCalendarInstance; + } + + public DateTime getFirstMonth() { + return calendar.getFirstMonth(); + } + + public Calendar getCalendar() { + return calendar; + } + + public void setCalendar(Calendar calendar) { + this.calendar = calendar; + } + + public Flowable observeChangesOnCalendar() { + return Flowable.create((FlowableEmitter emitter) -> { + CalendarObjectChangeListener objectChangeListener = emitter::onNext; + addChangeListener(objectChangeListener); + emitter.setCancellable(() -> removeChangeListener(objectChangeListener)); + }, BackpressureStrategy.BUFFER); + } + + private void addChangeListener(CalendarObjectChangeListener objectChangeListener) { + onChangeListenerList.add(objectChangeListener); + } + + private void removeChangeListener(CalendarObjectChangeListener objectChangeListener) { + onChangeListenerList.remove(objectChangeListener); + } + + private void emitOnChange(ChangeSet changeSet) { + for (CalendarObjectChangeListener onChangeListener : onChangeListenerList) { + onChangeListener.onChange(changeSet); + } + } + + private void emitOnChange(String changedField) { + CalendarChangeSet changeSet = new CalendarChangeSet(); + changeSet.addChangedField(changedField); + emitOnChange(changeSet); + } + + public DateTime getFirstSelectedDay() { + return calendar.getFirstSelectedDay(); + } + + public void setFirstSelectedDay(DateTime firstSelectedDay) { + if (calendar.getFirstSelectedDay() != firstSelectedDay) { + calendar.setFirstSelectedDay(firstSelectedDay); + emitOnChange(CalendarFields.FIRST_SELECTED_DAY); + } + } + + public DateTime getLastSelectedDay() { + return calendar.getLastSelectedDay(); + } + + public void setLastSelectedDay(DateTime lastSelectedDay) { + if (calendar.getLastSelectedDay() != lastSelectedDay) { + calendar.setLastSelectedDay(lastSelectedDay); + emitOnChange(CalendarFields.LAST_SELECTED_DAY); + } + } + + public DateTime getCurrentMonth() { + return calendar.getCurrentMonth(); + } + + public void setCurrentMonth(DateTime currentMonth) { + if (calendar.getCurrentMonth() != currentMonth) { + calendar.setCurrentMonth(currentMonth); + emitOnChange(CalendarFields.CURRENT_MONTH); + } + } + + public List getMonths() { + return calendar.getMonths(); + } + + public void setMonths(List months) { + if (calendar.getMonths() != months) { + calendar.setMonths(months); + emitOnChange(CalendarFields.MONTHS); + } + } + + public boolean isMultipleSelectionEnabled() { + return calendar.isMultipleSelectionEnabled(); + } + + public void setMultipleSelection(boolean multipleSelection) { + if (calendar.isMultipleSelectionEnabled() != multipleSelection) { + calendar.setMultipleSelection(multipleSelection); + emitOnChange(CalendarFields.MULTIPLE_SELECTION); + } + } + + public int getFirstDayOfWeek() { + return calendar.getFirstDayOfWeek(); + } + + public void setFirstDayOfWeek(int firstDayOfWeek) { + if (calendar.getFirstDayOfWeek() != firstDayOfWeek) { + calendar.setFirstDayOfWeek(firstDayOfWeek); + emitOnChange(CalendarFields.FIRST_DAY_OF_WEEK); + } + } + + public interface ChangeSet { + List getChangedFields(); + + boolean isFieldChanged(String fieldName); + + String toString(); + } + + public interface CalendarObjectChangeListener { + void onChange(ChangeSet changeSet); + } + + private class CalendarChangeSet implements ChangeSet { + private List changedFields = new ArrayList<>(); + + public void setChangedFiels(List changedFields) { + this.changedFields = changedFields; + } + + public void addChangedField(String changedField) { + this.changedFields.add(changedField); + } + + @Override + public List getChangedFields() { + return changedFields; + } + + @Override + public boolean isFieldChanged(String fieldName) { + return changedFields.contains(fieldName); + } + + @Override + public String toString() { + String fieldChanges = ""; + for (String fieldChanged : changedFields) { + fieldChanges += " " + fieldChanged; + } + return fieldChanges; + } + } +} \ No newline at end of file diff --git a/library/src/main/java/com/francesco/furlan/customizablecalendar/library/interactors/LayoutInteractor.java b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/interactors/LayoutInteractor.java new file mode 100644 index 0000000..835e67e --- /dev/null +++ b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/interactors/LayoutInteractor.java @@ -0,0 +1,21 @@ +package com.francesco.furlan.customizablecalendar.library.interactors; + +import android.support.annotation.LayoutRes; + +/** + * Created by francescofurlan on 26/06/17. + */ + +public interface LayoutInteractor { + void setCustomizableCalendarLayoutResId(@LayoutRes int resId); + + void setHeaderLayoutResId(@LayoutRes int resId); + + void setWeekDayResId(@LayoutRes int resId); + + void setSubViewResId(@LayoutRes int resId); + + void setMonthResId(@LayoutRes int resId); + + void setDayResId(@LayoutRes int resId); +} diff --git a/library/src/main/java/com/francesco/furlan/customizablecalendar/library/interactors/ViewInjector.java b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/interactors/ViewInjector.java new file mode 100644 index 0000000..84e8097 --- /dev/null +++ b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/interactors/ViewInjector.java @@ -0,0 +1,20 @@ +package com.francesco.furlan.customizablecalendar.library.interactors; + +import com.francesco.furlan.customizablecalendar.library.view.CalendarView; +import com.francesco.furlan.customizablecalendar.library.view.HeaderView; +import com.francesco.furlan.customizablecalendar.library.view.SubView; +import com.francesco.furlan.customizablecalendar.library.view.WeekDaysView; + +/** + * Created by francescofurlan on 30/06/17. + */ + +public interface ViewInjector { + void injectCalendarView(CalendarView calendarView); + + void injectHeaderView(HeaderView headerView); + + void injectSubView(SubView subView); + + void injectWeekDaysView(WeekDaysView weekDaysView); +} diff --git a/library/src/main/java/com/francesco/furlan/customizablecalendar/library/interactors/ViewInteractor.java b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/interactors/ViewInteractor.java new file mode 100644 index 0000000..c5085aa --- /dev/null +++ b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/interactors/ViewInteractor.java @@ -0,0 +1,45 @@ +package com.francesco.furlan.customizablecalendar.library.interactors; + +import android.view.View; +import android.view.ViewGroup; + +import com.francesco.furlan.customizablecalendar.library.adapter.WeekDaysViewAdapter; +import com.francesco.furlan.customizablecalendar.library.model.CalendarItem; + +import org.joda.time.DateTime; + +import java.util.List; + +/** + * Created by francescofurlan on 26/06/17. + */ + +public interface ViewInteractor { + void onCustomizableCalendarBindView(View view); + + void onHeaderBindView(ViewGroup view); + + void onWeekDaysBindView(View view); + + void onWeekDayBindView(WeekDaysViewAdapter.WeekDayVH holder, String weekDay); + + void onSubViewBindView(View view, String month); + + void onCalendarBindView(View view); + + void onMonthBindView(View view); + + View onMonthCellBindView(View view, CalendarItem currentItem); + + boolean hasImplementedDayCalculation(); + + List calculateDays(int year, int month, int firstDayOfMonth, int lastDayOfMonth); + + boolean hasImplementedSelection(); + + int setSelected(boolean multipleSelection, DateTime dateSelected); + + boolean hasImplementedMonthCellBinding(); + + View getMonthGridView(View rootView); +} diff --git a/library/src/main/java/com/francesco/furlan/customizablecalendar/library/model/Calendar.java b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/model/Calendar.java new file mode 100644 index 0000000..3e1731b --- /dev/null +++ b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/model/Calendar.java @@ -0,0 +1,92 @@ +package com.francesco.furlan.customizablecalendar.library.model; + +import org.joda.time.DateTime; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +/** + * Created by francescofurlan on 27/06/17. + */ + +public class Calendar { + private DateTime firstMonth; + private DateTime firstSelectedDay; + private DateTime lastSelectedDay; + private DateTime currentMonth; + private List months; + private boolean multipleSelection; + private int firstDayOfWeek; + + public Calendar(DateTime firstMonth, DateTime lastMonth) { + this.firstMonth = firstMonth; + this.firstDayOfWeek = java.util.Calendar.getInstance(Locale.getDefault()).getFirstDayOfWeek(); + + int startMonth = firstMonth.getMonthOfYear() + 1; + int endMonth = lastMonth.getMonthOfYear(); + + months = new ArrayList<>(); + + months.add(firstMonth); + currentMonth = firstMonth; + + DateTime monthToAdd = new DateTime(firstMonth.getYear(), startMonth, 1, 0, 0); + for (int i = startMonth; i <= endMonth; i++) { + months.add(monthToAdd); + monthToAdd = monthToAdd.plusMonths(1); + } + } + + public DateTime getFirstSelectedDay() { + return firstSelectedDay; + } + + public void setFirstSelectedDay(DateTime firstSelectedDay) { + this.firstSelectedDay = firstSelectedDay; + } + + public DateTime getLastSelectedDay() { + return lastSelectedDay; + } + + public void setLastSelectedDay(DateTime lastSelectedDay) { + this.lastSelectedDay = lastSelectedDay; + } + + public DateTime getCurrentMonth() { + return currentMonth; + } + + public void setCurrentMonth(DateTime currentMonth) { + this.currentMonth = currentMonth; + } + + public List getMonths() { + return months; + } + + public void setMonths(List months) { + this.months = months; + } + + public boolean isMultipleSelectionEnabled() { + return multipleSelection; + } + + public void setMultipleSelection(boolean multipleSelection) { + this.multipleSelection = multipleSelection; + } + + public int getFirstDayOfWeek() { + return firstDayOfWeek; + } + + public void setFirstDayOfWeek(int firstDayOfWeek) { + this.firstDayOfWeek = firstDayOfWeek; + } + + public DateTime getFirstMonth() { + return firstMonth; + } +} diff --git a/library/src/main/java/com/francesco/furlan/customizablecalendar/library/model/CalendarFields.java b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/model/CalendarFields.java new file mode 100644 index 0000000..b393cb7 --- /dev/null +++ b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/model/CalendarFields.java @@ -0,0 +1,36 @@ +package com.francesco.furlan.customizablecalendar.library.model; + +import android.support.annotation.StringDef; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import static com.francesco.furlan.customizablecalendar.library.model.CalendarFields.CURRENT_MONTH; +import static com.francesco.furlan.customizablecalendar.library.model.CalendarFields.FIRST_DAY_OF_WEEK; +import static com.francesco.furlan.customizablecalendar.library.model.CalendarFields.FIRST_SELECTED_DAY; +import static com.francesco.furlan.customizablecalendar.library.model.CalendarFields.LAST_SELECTED_DAY; +import static com.francesco.furlan.customizablecalendar.library.model.CalendarFields.MONTHS; +import static com.francesco.furlan.customizablecalendar.library.model.CalendarFields.MULTIPLE_SELECTION; + +/** + * Created by francescofurlan on 30/06/17. + */ + +@StringDef({ + FIRST_SELECTED_DAY, + LAST_SELECTED_DAY, + CURRENT_MONTH, + MONTHS, + MULTIPLE_SELECTION, + FIRST_DAY_OF_WEEK +}) + +@Retention(RetentionPolicy.SOURCE) +public @interface CalendarFields { + String FIRST_SELECTED_DAY = "firstSelectedDay"; + String LAST_SELECTED_DAY = "lastSelectedDay"; + String CURRENT_MONTH = "currentMonth"; + String MONTHS = "months"; + String MULTIPLE_SELECTION = "multipleSelection"; + String FIRST_DAY_OF_WEEK = "firstDayOfWeek"; +} \ No newline at end of file diff --git a/library/src/main/java/com/francesco/furlan/customizablecalendar/library/model/CalendarItem.java b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/model/CalendarItem.java new file mode 100644 index 0000000..be592f5 --- /dev/null +++ b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/model/CalendarItem.java @@ -0,0 +1,74 @@ +package com.francesco.furlan.customizablecalendar.library.model; + +import org.joda.time.DateTime; + +import java.util.Calendar; + +/** + * Created by francescofurlan on 23/06/17. + */ + +public class CalendarItem { + private long id; + private DateTime dateTime; + private boolean selected; + + public CalendarItem(Calendar calendar) { + this.dateTime = new DateTime(calendar); + this.id = calendar.getTimeInMillis(); + } + + public CalendarItem(DateTime dateTime) { + this.dateTime = dateTime; + this.id = dateTime.getMillis(); + } + + public CalendarItem(int day, int month, int year) { + this.dateTime = new DateTime(year, month, day, 0, 0); + this.id = dateTime.getMillis(); + } + + public DateTime getDateTime() { + return dateTime; + } + + public void setDateTime(DateTime dateTime) { + this.dateTime = dateTime; + } + + public boolean isSelectable() { + return selected; + } + + public void setSelectable(boolean selected) { + this.selected = selected; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public int compareTo(DateTime today) { + return dateTime.compareTo(today); + } + + public String getDayString() { + return getDay() + ""; + } + + public int getDay() { + return dateTime.getDayOfMonth(); + } + + public int getMonth() { + return dateTime.getMonthOfYear(); + } + + public int getYear() { + return dateTime.getYear(); + } +} diff --git a/library/src/main/java/com/francesco/furlan/customizablecalendar/library/presenter/implementations/CustomizableCalendarPresenterImpl.java b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/presenter/implementations/CustomizableCalendarPresenterImpl.java new file mode 100644 index 0000000..a19665c --- /dev/null +++ b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/presenter/implementations/CustomizableCalendarPresenterImpl.java @@ -0,0 +1,150 @@ +package com.francesco.furlan.customizablecalendar.library.presenter.implementations; + +import android.support.annotation.LayoutRes; +import android.text.TextUtils; +import android.view.View; + +import com.francesco.furlan.customizablecalendar.library.interactors.AUCalendar; +import com.francesco.furlan.customizablecalendar.library.interactors.ViewInteractor; +import com.francesco.furlan.customizablecalendar.library.model.CalendarFields; +import com.francesco.furlan.customizablecalendar.library.presenter.interfeaces.CustomizableCalendarPresenter; +import com.francesco.furlan.customizablecalendar.library.view.CalendarView; +import com.francesco.furlan.customizablecalendar.library.view.CustomizableCalendarView; +import com.francesco.furlan.customizablecalendar.library.view.HeaderView; +import com.francesco.furlan.customizablecalendar.library.view.SubView; +import com.francesco.furlan.customizablecalendar.library.view.WeekDaysView; + +import org.joda.time.DateTime; + +import java.util.Locale; + +import io.reactivex.disposables.CompositeDisposable; + +/** + * Created by francescofurlan on 23/06/17. + */ + +public class CustomizableCalendarPresenterImpl implements CustomizableCalendarPresenter { + private AUCalendar calendar; + private CalendarView calendarView; + private HeaderView headerView; + private SubView subView; + private WeekDaysView weekDaysView; + private ViewInteractor viewInteractor; + private CustomizableCalendarView view; + private CompositeDisposable subscriptions = new CompositeDisposable(); + + @Override + public void injectViewInteractor(ViewInteractor viewInteractor) { + this.viewInteractor = viewInteractor; + } + + @Override + public void setLayoutResId(@LayoutRes int layoutResId) { + view.setLayoutResId(layoutResId); + } + + @Override + public void setView(CustomizableCalendarView view) { + this.view = view; + if (viewInteractor != null) { + view.injectViewInteractor(viewInteractor); + } + calendar = AUCalendar.getInstance(); + subscriptions.add( + calendar.observeChangesOnCalendar() + .subscribe(changeSet -> { + if (changeSet.isFieldChanged(CalendarFields.CURRENT_MONTH)) { + onCurrentMonthChanged(calendar.getCurrentMonth()); + } + if (changeSet.isFieldChanged(CalendarFields.FIRST_DAY_OF_WEEK)) { + if (weekDaysView != null) { + weekDaysView.onFirstDayOfWeek(calendar.getFirstDayOfWeek()); + } + if (calendarView != null) { + calendarView.refreshData(); + } + } + }) + ); + } + + @Override + public void onBindView(View rootView) { + viewInteractor.onCustomizableCalendarBindView(rootView); + } + + private void onCurrentMonthChanged(DateTime currentMonth) { + String month = currentMonth.toString("MMMMM", Locale.getDefault()); + if (view != null && !TextUtils.isEmpty(month)) { + String formattedMonth = month.substring(0, 1).toUpperCase() + month.substring(1); + view.onCurrentMonthChanged(formattedMonth); + } + } + + @Override + public void injectCalendarView(CalendarView calendarView) { + this.calendarView = calendarView; + this.calendarView.injectViewInteractor(viewInteractor); + } + + @Override + public void injectHeaderView(HeaderView headerView) { + this.headerView = headerView; + this.headerView.injectViewInteractor(viewInteractor); + } + + @Override + public void injectSubView(SubView subView) { + this.subView = subView; + this.subView.injectViewInteractor(viewInteractor); + } + + @Override + public void injectWeekDaysView(WeekDaysView weekDaysView) { + this.weekDaysView = weekDaysView; + this.weekDaysView.injectViewInteractor(viewInteractor); + } + +// @Override +// public void setCustomizableCalendarLayoutResId(@LayoutRes int resId) { +// if (view != null) { +// view.setLayoutResId(resId); +// } +// } +// +// @Override +// public void setHeaderLayoutResId(@LayoutRes int resId) { +// if (headerView != null) { +// headerView.setLayoutResId(resId); +// } +// } +// +// @Override +// public void setWeekDayResId(@LayoutRes int resId) { +// if (weekDaysView != null) { +// weekDaysView.setLayoutResId(resId); +// } +// } +// +// @Override +// public void setSubViewResId(@LayoutRes int resId) { +// if (subView != null) { +// subView.setLayoutResId(resId); +// } +// } +// +// @Override +// public void setMonthResId(@LayoutRes int resId) { +// if (calendarView != null) { +// calendarView.setMonthLayoutResId(resId); +// } +// } +// +// @Override +// public void setDayResId(@LayoutRes int resId) { +// if (calendarView != null) { +// calendarView.setDayLayoutResId(resId); +// } +// } +} diff --git a/library/src/main/java/com/francesco/furlan/customizablecalendar/library/presenter/interfeaces/BasePresenter.java b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/presenter/interfeaces/BasePresenter.java new file mode 100644 index 0000000..b116444 --- /dev/null +++ b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/presenter/interfeaces/BasePresenter.java @@ -0,0 +1,21 @@ +package com.francesco.furlan.customizablecalendar.library.presenter.interfeaces; + +import android.support.annotation.LayoutRes; +import android.view.View; + +import com.francesco.furlan.customizablecalendar.library.interactors.ViewInteractor; +import com.francesco.furlan.customizablecalendar.library.view.BaseView; + +/** + * Created by francescofurlan on 23/06/17. + */ + +public interface BasePresenter { + void setView(T view); + + void onBindView(View rootView); + + void injectViewInteractor(ViewInteractor viewInteractor); + + void setLayoutResId(@LayoutRes int layoutResId); +} \ No newline at end of file diff --git a/library/src/main/java/com/francesco/furlan/customizablecalendar/library/presenter/interfeaces/CustomizableCalendarPresenter.java b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/presenter/interfeaces/CustomizableCalendarPresenter.java new file mode 100644 index 0000000..72557a9 --- /dev/null +++ b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/presenter/interfeaces/CustomizableCalendarPresenter.java @@ -0,0 +1,11 @@ +package com.francesco.furlan.customizablecalendar.library.presenter.interfeaces; + +import com.francesco.furlan.customizablecalendar.library.interactors.ViewInjector; +import com.francesco.furlan.customizablecalendar.library.view.CustomizableCalendarView; + +/** + * Created by francescofurlan on 23/06/17. + */ + +public interface CustomizableCalendarPresenter extends BasePresenter, ViewInjector { +} diff --git a/library/src/main/java/com/francesco/furlan/customizablecalendar/library/utils/DateUtils.java b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/utils/DateUtils.java new file mode 100644 index 0000000..b1998ea --- /dev/null +++ b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/utils/DateUtils.java @@ -0,0 +1,31 @@ +package com.francesco.furlan.customizablecalendar.library.utils; + +import java.util.Calendar; + +/** + * Created by francescofurlan on 23/06/17. + */ + +public class DateUtils { + public static int getDaysInMonth(int month, int year) { + switch (month) { + case Calendar.JANUARY: + case Calendar.MARCH: + case Calendar.MAY: + case Calendar.JULY: + case Calendar.AUGUST: + case Calendar.OCTOBER: + case Calendar.DECEMBER: + return 31; + case Calendar.APRIL: + case Calendar.JUNE: + case Calendar.SEPTEMBER: + case Calendar.NOVEMBER: + return 30; + case Calendar.FEBRUARY: + return (year % 4 == 0) ? 29 : 28; + default: + throw new IllegalArgumentException("Invalid Month"); + } + } +} \ No newline at end of file diff --git a/library/src/main/java/com/francesco/furlan/customizablecalendar/library/view/BaseView.java b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/view/BaseView.java new file mode 100644 index 0000000..059a98b --- /dev/null +++ b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/view/BaseView.java @@ -0,0 +1,20 @@ +package com.francesco.furlan.customizablecalendar.library.view; + +import android.support.annotation.LayoutRes; + +import com.francesco.furlan.customizablecalendar.library.interactors.ViewInteractor; +import com.francesco.furlan.customizablecalendar.library.presenter.interfeaces.CustomizableCalendarPresenter; + +/** + * Created by francescofurlan on 23/06/17. + */ + +public interface BaseView { + void refreshData(); + + void setLayoutResId(@LayoutRes int layoutResId); + + void injectViewInteractor(ViewInteractor viewInteractor); + + void injectPresenter(CustomizableCalendarPresenter presenter); +} \ No newline at end of file diff --git a/library/src/main/java/com/francesco/furlan/customizablecalendar/library/view/CalendarView.java b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/view/CalendarView.java new file mode 100644 index 0000000..2e622ab --- /dev/null +++ b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/view/CalendarView.java @@ -0,0 +1,13 @@ +package com.francesco.furlan.customizablecalendar.library.view; + +import android.support.annotation.LayoutRes; + +/** + * Created by francescofurlan on 03/07/17. + */ + +public interface CalendarView extends BaseView { + void setMonthLayoutResId(@LayoutRes int layoutResId); + + void setDayLayoutResId(@LayoutRes int layoutResId); +} diff --git a/library/src/main/java/com/francesco/furlan/customizablecalendar/library/view/CustomizableCalendarView.java b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/view/CustomizableCalendarView.java new file mode 100644 index 0000000..b3302ce --- /dev/null +++ b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/view/CustomizableCalendarView.java @@ -0,0 +1,9 @@ +package com.francesco.furlan.customizablecalendar.library.view; + +/** + * Created by francescofurlan on 23/06/17. + */ + +public interface CustomizableCalendarView extends BaseView { + void onCurrentMonthChanged(String month); +} diff --git a/library/src/main/java/com/francesco/furlan/customizablecalendar/library/view/HeaderView.java b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/view/HeaderView.java new file mode 100644 index 0000000..b27c10b --- /dev/null +++ b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/view/HeaderView.java @@ -0,0 +1,8 @@ +package com.francesco.furlan.customizablecalendar.library.view; + +/** + * Created by francescofurlan on 30/06/17. + */ + +public interface HeaderView extends BaseView { +} diff --git a/library/src/main/java/com/francesco/furlan/customizablecalendar/library/view/MonthView.java b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/view/MonthView.java new file mode 100644 index 0000000..bab490b --- /dev/null +++ b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/view/MonthView.java @@ -0,0 +1,16 @@ +package com.francesco.furlan.customizablecalendar.library.view; + + +import org.joda.time.DateTime; + +/** + * Created by francescofurlan on 23/06/17. + */ + +public interface MonthView extends BaseView { + void setSelected(DateTime dateSelected); + + void refreshDays(); + + void unsubscribe(); +} diff --git a/library/src/main/java/com/francesco/furlan/customizablecalendar/library/view/SubView.java b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/view/SubView.java new file mode 100644 index 0000000..2e9d26b --- /dev/null +++ b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/view/SubView.java @@ -0,0 +1,9 @@ +package com.francesco.furlan.customizablecalendar.library.view; + +/** + * Created by francescofurlan on 30/06/17. + */ + +public interface SubView extends BaseView { + void onMonthChanged(String month); +} diff --git a/library/src/main/java/com/francesco/furlan/customizablecalendar/library/view/WeekDaysView.java b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/view/WeekDaysView.java new file mode 100644 index 0000000..470d84e --- /dev/null +++ b/library/src/main/java/com/francesco/furlan/customizablecalendar/library/view/WeekDaysView.java @@ -0,0 +1,9 @@ +package com.francesco.furlan.customizablecalendar.library.view; + +/** + * Created by francescofurlan on 30/06/17. + */ + +public interface WeekDaysView extends BaseView { + void onFirstDayOfWeek(int firstDayOfWeek); +} diff --git a/library/src/main/res/drawable/circle.xml b/library/src/main/res/drawable/circle.xml new file mode 100644 index 0000000..80b2d78 --- /dev/null +++ b/library/src/main/res/drawable/circle.xml @@ -0,0 +1,20 @@ + + + + + + + + \ No newline at end of file diff --git a/library/src/main/res/drawable/empty_circle.xml b/library/src/main/res/drawable/empty_circle.xml new file mode 100644 index 0000000..4ecefb9 --- /dev/null +++ b/library/src/main/res/drawable/empty_circle.xml @@ -0,0 +1,19 @@ + + + + + + + + \ No newline at end of file diff --git a/library/src/main/res/drawable/left_rounded_rectangle.xml b/library/src/main/res/drawable/left_rounded_rectangle.xml new file mode 100644 index 0000000..3b1868d --- /dev/null +++ b/library/src/main/res/drawable/left_rounded_rectangle.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/library/src/main/res/drawable/rectangle.xml b/library/src/main/res/drawable/rectangle.xml new file mode 100644 index 0000000..977ff60 --- /dev/null +++ b/library/src/main/res/drawable/rectangle.xml @@ -0,0 +1,4 @@ + + + \ No newline at end of file diff --git a/library/src/main/res/drawable/right_rounded_rectangle.xml b/library/src/main/res/drawable/right_rounded_rectangle.xml new file mode 100644 index 0000000..31798f0 --- /dev/null +++ b/library/src/main/res/drawable/right_rounded_rectangle.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/library/src/main/res/layout/calendar_cell.xml b/library/src/main/res/layout/calendar_cell.xml new file mode 100644 index 0000000..75e6084 --- /dev/null +++ b/library/src/main/res/layout/calendar_cell.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/library/src/main/res/layout/calendar_view.xml b/library/src/main/res/layout/calendar_view.xml new file mode 100644 index 0000000..a8f4f0e --- /dev/null +++ b/library/src/main/res/layout/calendar_view.xml @@ -0,0 +1,16 @@ + + + + + + \ No newline at end of file diff --git a/library/src/main/res/layout/customizable_calendar.xml b/library/src/main/res/layout/customizable_calendar.xml new file mode 100644 index 0000000..aaf1fa0 --- /dev/null +++ b/library/src/main/res/layout/customizable_calendar.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/library/src/main/res/layout/sub_view.xml b/library/src/main/res/layout/sub_view.xml new file mode 100644 index 0000000..667c026 --- /dev/null +++ b/library/src/main/res/layout/sub_view.xml @@ -0,0 +1,14 @@ + + + + + + \ No newline at end of file diff --git a/library/src/main/res/layout/week_day_view.xml b/library/src/main/res/layout/week_day_view.xml new file mode 100644 index 0000000..6424868 --- /dev/null +++ b/library/src/main/res/layout/week_day_view.xml @@ -0,0 +1,15 @@ + + + + + + \ No newline at end of file diff --git a/library/src/main/res/values/attrs.xml b/library/src/main/res/values/attrs.xml new file mode 100644 index 0000000..d2fdacd --- /dev/null +++ b/library/src/main/res/values/attrs.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/library/src/main/res/values/colors.xml b/library/src/main/res/values/colors.xml new file mode 100644 index 0000000..7491ed1 --- /dev/null +++ b/library/src/main/res/values/colors.xml @@ -0,0 +1,5 @@ + + + #3F51B5 + #303F9F + \ No newline at end of file diff --git a/library/src/main/res/values/dimens.xml b/library/src/main/res/values/dimens.xml new file mode 100644 index 0000000..dc09b04 --- /dev/null +++ b/library/src/main/res/values/dimens.xml @@ -0,0 +1,4 @@ + + + 240dp + \ No newline at end of file