muraee / horizontal-calendar Goto Github PK
View Code? Open in Web Editor NEWA material horizontal calendar view for Android based on RecyclerView
License: Apache License 2.0
A material horizontal calendar view for Android based on RecyclerView
License: Apache License 2.0
I want to reinitialize the HorizontalCalendar every time I select Spinner item.
But I get below error:
java.lang.IllegalStateException: An instance of OnFlingListener already set.
For following code :
sp_bkapt_select_pgm.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
System.out.println("I m setSpinner : " + adapterView.getItemAtPosition(i));
horizontalCalendar_viewSch = new HorizontalCalendar.Builder(Activity_ViewAppointmentsSchedule.this, R.id.horizontalCalendar_viewSch)
.startDate(actualStrtDate)
.endDate(endDate)
.datesNumberOnScreen(5)
.dayNameFormat("EEE")
.dayNumberFormat("dd")
.monthFormat("MMM")
.showDayName(true)
.showMonthName(true)
.defaultSelectedDate(strtDate)
.textColor(Color.parseColor("#191919"), Color.WHITE)
.build();
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
i want to change the color of current date.
Hi,
I have a small issue here, today it is 22nd January, but default date displayed on calendar is 26th January, even when I call "goToday" or "selectDate".
Also, the methods "getDateEndCalendar" and "getDateStartCalendar" return 22nd December and 22nd February, which is correct, but rendered dates are from 20th December to 24th February.
This is my code, I am not doing anything special.
calendar = new HorizontalCalendar.Builder(layout, R.id.date_picker).build();
calendar.setCalendarListener(new CalendarListener(this));
and layout file
<devs.mulham.horizontalcalendar.HorizontalCalendarView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#fff"
app:textColorNormal="#000"
app:textColorSelected="#fff"
app:selectorColor="#000"
app:selectedDateBackground="#000"
android:id="@+id/date_picker" />
EDIT: Building on Android 4.4.2 with appcompat-v7:25.1.0
Cant access the first few day tabs in the calendar tab when nested in fragment tabs using the below, wants to page across to previous parent fragment tabs tab or cant access touch event either;
// Add Fragments to Tabs in MainActivity
private void setupViewPager(ViewPager viewPager) {
Adapter adapter = new Adapter(getSupportFragmentManager());
adapter.addFragment(new PlaceHolderFragment(), "Latest");
//the Calendar fragment here
adapter.addFragment(new FixturesFragment(), "Calendar");
adapter.addFragment(new CalanderTabFragment(), "Results");
viewPager.setAdapter(adapter);
}
Select a date and calendarListener.onDateSelected() callback two times . Every time a date is selected, I need to access the network interface once , causes my code to access the two network interface,how to fix it?
Bugs:
In the application, I set my own layout, instead of the default. (By creating a layout with the same name in the layout directory: https://developer.android.com/studio/write/add-resources.html#resource_merging )
In this layout I set the width to 60dp and ran it on a device with a resolution of 480x800. I record the video: RecordWithLogs.zip
Central date selected
The date was chosen after the central one.
Hi,
Great work!!!
Issue observed :
I cannot select the dates that are displayed starting.
eg : If date range is from Jan 22nd to Feb 28th, when the screen loads, by default selected date is Jan 24th and i cannot make clicks on dates Jan 22nd and Jan 23rd.
Regards,
Titto Jose.
If now current date if 27.04 and after double or more click on 25.04 (for example) date not changed
Hello @Mulham-Raee
It would be nice to have a possibility to change the font size of the day number, day name and month name.
Customize it directly inside the layout or programmatically.
What do you think about that addition, I am happy to open up a PR for it.
Regards!
It shows always error while calling horizontalCalendar.getSelectedDate();
I've noticed that when performing a fast scrolling of the view, there is sometimes lag. a jump between frames.
Enabling the "profile GPU rendering", I noticed that indeed it can get very slow :
At first I thought it's something with the adapter onBindViewHolder function, but it's far from the truth.
The real reason for this, is that the scrolling constantly calls notifyDataSetChanged, as I wrote here:
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
//On Scroll, agenda is refresh to update background colors
post(new Runnable() {
@Override
public void run() {
mCalendarAdapter.notifyDataSetChanged();
}
});
Commenting this part, scrolling becomes super smooth, but of course there won't be any selection of items during scroll:
Please do think of a better way to update the views.
It doesn't make sense to update all of the views, whenever you scroll, or even whenever a new selection is made. Only 2 views are supposed to be updated, and only when the selection has changed.
HI Mulham,
Builder Class I done enable for click listener
public Builder setEnable(boolean enable){
this.enable = enable;
return this;
}
HorizontalCalendarAdapter class I modified.
if(enable) {
holder.rootView.setOnClickListener(new View.OnClickListener() {
@OverRide
public void onClick(View v) {
//int stepX = getStepX(v);
Date date = datesList.get(holder.getAdapterPosition());
if (!date.before(horizontalCalendar.getDateStartCalendar())
&& !date.after(horizontalCalendar.getDateEndCalendar())) {
//horizontalCalendarView.smoothScrollBy(stepX, 0);
horizontalCalendarView.setSmoothScrollSpeed(HorizontalLayoutManager.SPEED_SLOW);
horizontalCalendar.centerCalendarToPosition(holder.getAdapterPosition());
}
}
});
holder.rootView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
Date date = datesList.get(holder.getAdapterPosition());
HorizontalCalendarListener calendarListener = horizontalCalendar.getCalendarListener();
if (calendarListener != null && !date.before(horizontalCalendar.getDateStartCalendar())
&& !date.after(horizontalCalendar.getDateEndCalendar())) {
return calendarListener.onDateLongClicked(date, holder.getAdapterPosition());
}
return false;
}
});
}
But I cannot stop Horizontal Scroll Listener. Because My project features requirements. Please help me out from my project issue!
Thanks in advance.
There is a crash while trying to add the calender to a fragment instead of activity we can demonstrate a sample for this
when datesNumberOnScreen(3),first open the application.the 207/11/02 is selected,but the toast show 2017/11/01 is selected,
@Mulham-Raee
final Calendar defaultDate = Calendar.getInstance();
defaultDate.add(Calendar.MONTH, -1);
defaultDate.add(Calendar.DAY_OF_WEEK, +3);
horizontalCalendar.post(new Runnable() {
@OverRide
public void run() {
Log.i("MainActivity", "defaultDate "+defaultDate.getTime());
horizontalCalendar.selectDate(defaultDate.getTime(), true);
}
});
But response is two date is selected. How can i fix this issue?
Reason :
int selectedItemPosition = horizontalCalendarView.getPositionOfCenterItem();
Current Date & Default Date 1st time loading centerItemPostion.
also i gave
**horizontalCalendar.goToday(true);
**horizontalCalendar.selectDate(new Date(),true);
so for above settings also it shows it is not selected current date.
? It has to select by default current date.
?
HorizontalCalendar horizontalCalendar = new HorizontalCalendar.Builder(this, R.id.calendarView)
.startDate(startDate.getTime())
.endDate(endDate.getTime())
.datesNumberOnScreen(7)
.dayNameFormat("EEE")
.dayNumberFormat("dd")
.monthFormat("MMM")
.showDayName(true)
.showMonthName(true)
.selectedDateBackground(ContextCompat.getDrawable(this, R.drawable.ic_selectable_background))
.defaultSelectedDate(defaultDate.getTime())
.textColor(Color.GRAY, Color.rgb(15,26,42))
.selectorColor(Color.rgb(15,26,42))
.build();
Above is my constructor am using.
- Android Version:
- Horizontal-Calendar Version:
I triet this library. On Activities work fine, but on fragments your calendar does not scroll to todat date and not show corect dates.
Thank you for the work that's gone into this very useful library.
Unfortunately I am experiencing an issue where the calendar always defaults to tomorrow's date (occasionally yesterday's). I'am configuring the Calendar as shown below...
`private HorizontalCalendar initCalendar() {
Calendar endDate = Calendar.getInstance();
endDate.add(Calendar.DAY_OF_MONTH, 1);
Calendar startDate = Calendar.getInstance();
startDate.add(Calendar.DAY_OF_MONTH, -1);
return new HorizontalCalendar.Builder(this, R.id.calendarView)
.startDate(startDate.getTime())
.endDate(endDate.getTime())
.datesNumberOnScreen(3) // Number of Dates cells shown on screen (Recommended 5)
.dayNameFormat("EEE") // WeekDay text format
.dayNumberFormat("dd") // Date format
.monthFormat("MMM") // Month format
.showDayName(true) // Show or Hide dayName text
.showMonthName(true) // Show or Hide month text
.textColor(Color.LTGRAY, Color.WHITE) // Text color for none selected Dates
.selectorColor(Color.BLUE) // Color of the selection indicator bar (default to colorAccent).
.build();
}`
The value of 'onDateSelected' when the calendar is initialised is always today's date yet the Calendar shows tomorrow as selected. I understand that the recommended 'datesNumberOnScreen' value is 5 and i've found that this issue doesn't happen when changing the value of 5.
I would ideally like to show 3 dates if this is possible, and I've tried setting defaultSelectedDate() to today and running goToday(true) without success.
I've tested a previous version of my project - with datesNumberOnScreen set to 3 - and it works as expected. This has started happening in a branch where I have made a number of upgrades to my project including upgrading to 'com.android.tools.build:gradle:3.0.1'
Any assistance with this issue would be much appreciated. Many thanks
I've noticed that before the view is used, an AsyncTask is executed that saves all dates in the range:
@Override
protected Void doInBackground(Void... params) {
//ArrayList of dates is set with all the dates between
//start and end date
GregorianCalendar calendar = new GregorianCalendar();
calendar.setTime(dateStartCalendar);
calendar.add(Calendar.DATE, -(numberOfDatesOnScreen / 2));
Date dateStartBefore = calendar.getTime();
calendar.setTime(dateEndCalendar);
calendar.add(Calendar.DATE, numberOfDatesOnScreen / 2);
Date dateEndAfter = calendar.getTime();
Date date = dateStartBefore;
while (!date.after(dateEndAfter)) {
mListDays.add(date);
calendar.setTime(date);
calendar.add(Calendar.DATE, 1);
date = calendar.getTime();
}
return null;
}
This is a bad thing:
Instead of this, the view should immediately go to the correct date.
The calculation can be done on the UI thread, in the onBindViewHolder callback, by comparing the current item position to the pivot date (the date you started from, or the start date).
startDate & endDate are exists but what about set default date I can't do it
selectDate() not working for me
Add localization by Locale.getDefault() or set it manually in Builder.
But it is necessary to provide for the correct spelling of words in all languages.
For example, in Russain not "марта" and "Март" (is it March).
Feature Request
make selected date not always in the center of the list
selected date always in the center of the list
- Android Version: 21
- Horizontal-Calendar Version:1.1.7
You should only refresh the views of the RecyclerView when needed.
Currently what you do is this:
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
//On Scroll, agenda is refresh to update background colors
post(new Runnable() {
@Override
public void run() {
mCalendarAdapter.notifyDataSetChanged();
}
});
...
}
First, the "post" is not needed because you are already on the UI thread.
Second, on most cases, when scrolling, the selected item doesn't change, so it's not needed to call notifyDataSetChanged.
Instead, you can check if the previously selected item is the same as the current one, and only if they are not, call notifyDataSetChanged.
@Mulham-Raee, I have the current month being displayed on the toolbar and in the library the month name above every date becomes redundant, can i remove it without adopting the library. If youd could provide this option as for date and day, it would be of great help
Currently I use this:
Calendar startDate = Calendar.getInstance();
startDate.setTime(new Date(0L));
Calendar endDate = Calendar.getInstance();
endDate.add(Calendar.YEAR, 120);
horizontalCalendar = new HorizontalCalendar.Builder(this, R.id.calendarView)
.startDate(startDate.getTime())
.endDate(endDate.getTime())
...
but what's the largest range this library support?
I was wondering if there is a way to use some markers or such thing to highlight a particular date, such as when the user has events on that date? For example, I would like to achieve something of this sort with the calendar (look at the right screen):
Is there a way to customize the calendar to achieve that?
Restricts me to scroll more towards right or left to select the boundary elements. So unable to select the boundary numbers.
horizontalCalendar.setCalendarListener-> onDateSelected function working fine
but when i using selectDate() to select the date
the date return result is correct but the selected position is -1
for example:
selectDate(11-11-2017)
but showing the selectedItem is (10-11-2017)
(the date return result is showing 11-11-2017<-correct
i think the problem is your position calculation wrong
When I scroll , and stop to position , date is selected twice time.
Hello buddy,
Great library and thank you for sharing this with us!
How would i disable scrolling or listen for scroll when user stopped scrolling at one date, so i can fetch data from server. Otherwise if he is scrolling fast, it will not be good for performance and maybe some data will not be loaded at right date.
Thank you in advance.
Greetz.
I certainly have a query, whether we can select the dates that forms an interval
Eg: Select dates between October 7- October 12
When the activity opens first today's default date is selected. Once I scroll and try to come back to today's default date, I cannot do so. My problem will be shown in this video:
https://drive.google.com/open?id=0B8wL31ixEiQybDQwVFlUQW44OFU
It seems that it works fine when I set number of items to be shown as 4 ".datesNumberOnScreen(4)" i.e. when the numbers are even. The problem occurs when I give numbers as 5, 3.
how to reset Horizontal-Calendar setting?
The key factor here is the true
immediate
argument. When false, it does it's thing animating to the date given and calls the HorizontalCalendarListener
's callback. When true, it immediately shifts the HorizontalCalendarView
but does not invoke the callback.
on 1.1.5
I got this error when i'm scrolling the calendar.
java.lang.ArrayIndexOutOfBoundsException: length=1021; index=-1 at java.util.ArrayList.get(ArrayList.java:306) at devs.mulham.horizontalcalendar.HorizontalCalendarAdapter$1.onClick(HorizontalCalendarAdapter.java:57) at android.view.View.performClick(View.java:4091) at android.view.View$PerformClick.run(View.java:17072) at android.os.Handler.handleCallback(Handler.java:615) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:153) at android.app.ActivityThread.main(ActivityThread.java:4987) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:821) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:584) at dalvik.system.NativeStart.main(Native Method)
I have downloaded the source code and I guess it because of adjustCalendarLocation method.
So I suggest remove it and add this code snippet into loadHorizontalCalendar() method
LinearSnapHelper snapHelper = new LinearSnapHelper();
snapHelper.attachToRecyclerView(calendarView);
calendarView.setOnFlingListener(snapHelper);
With this change, the display is much better
When changing date onDateSelected() called twice, once with old date and once more with new date.
why this behavior happens?
Clarification: It happens only when scrolling calendar and working right when clicking
Hello,
I'd like to use this amazing library in my application, the horizontal calendar under the action bar is intuitive and easy.
In my application i've got some records regarding Insurance's documents. I need to filter them basing only on the month and not the single day.
I want to use this library but i can't figure out how to display the 12 months instead every single day of the year.
Thanks.
To go straight to the given date, by using:
horizontalCalendar.goToday(true);
It doesn't always go so quickly to there. Depends on device or Android version
- Make the date range large. I used this:
#45- scroll a lot.
- Choose to go to current day.
- Android Version:
6.0.1 on OnePlus 2- Horizontal-Calendar Version:
1.1.8
See how slow it can be (took about 2 seconds to reach there) :
VID_20171024_121150 (1).zip
The purpose is to avoid overriding them by mistake.
I think that in the current repo, the only resource of this kind is "item_calendar.xml" .
Other than that, I don't think there is another one.
For fix bug with selection previous item when select day before current need change next method in HorizontalCalendarView:
public int getPositionOfCenterItem() {
int numberOfDatesOnScreen = horizontalCalendar.getNumberOfDatesOnScreen();
int firstVisibilePosition = getLayoutManager().findFirstCompletelyVisibleItemPosition();
if (firstVisibilePosition == -1) {
return -1;
}
return firstVisibilePosition + (numberOfDatesOnScreen / 2);
}
To:
public int getPositionOfCenterItem() {
int numberOfDatesOnScreen = horizontalCalendar.getNumberOfDatesOnScreen();
int firstVisiblePosition = getLayoutManager().findFirstVisibleItemPosition();
if (firstVisiblePosition == -1) {
return -1;
}
return firstVisiblePosition + (numberOfDatesOnScreen / 2);
}
The calendar is getting visible only on first tab not on others...
I'm having problem changing the selected date. Basically I have a button that should select "tomorrow"
public void onClick(View v) { Calendar tomorrow = Calendar.getInstance(); tomorrow.add(Calendar.DAY_OF_MONTH, 1); horizontalCalendar.selectDate(tomorrow); }
I never used Calendar or Date before so maybe is just an error in my comprehension.
This is the Horizontal Calendar build:
final HorizontalCalendar horizontalCalendar = new HorizontalCalendar.Builder(view, R.id.calendarView) .startDate(startDate.getTime()) .endDate(endDate.getTime()) .showMonthName(false) .build();
Awesome work! It would be great if we could add a custom drawable or image background to the selected date.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.