B4A Library MultiDayCalendarView

This is a (partly) wrapper for this Github project. It is a "starter" for the request posted by @jahswani in the Business Forum

Posting the following:
1. B4A project demonstrating functionality added thus far
2. The Java Code - do with it / change it / amend it whichever way you like
3. B4A library files - copy them to your additional library folder
4. You will also need android-support-v4.jar to be in you additional library folder. You can download it from here https://www.dropbox.com/s/qmggn0wm5a6bqa9/android-support-v4.jar?dl=0

How to use:
1. See code in the attached project to add an Event via B4A code
2. Touch and empty cell - it will be highlighted in Yellow (see code to change the color). Then touch the same cell again. An Event will be added to the Calendar based on the B4A code:
B4X:
mdcv1.ClickEventName = "Morning Meeting"
mdcv1.ClickEventDetail = "All Operations Personnel"
mdcv1.ClickEventColor = Colors.DarkGray
3. Use your finger to scroll up/down (time) and left / right (days)
4. The following 3 events will be raised in the B4A project
B4X:
Sub mdcv1_event_selected(eventname As String, eventdetail As String)

    Log("B4A: calendar eventname = " & eventname)
    Log("B4A: calendar eventdetail = " & eventdetail)
    nativeMe.RunMethod("showToastMessage", Array(eventname & " : " & eventdetail))

End Sub

Sub mdcv1_calendar_scrolling(firstday As String)

    Log("B4A: first day = " & firstday)

End Sub


Sub mdcv1_event_added(eventstartdatetime As Long, clickeventname As String, clickeventdetail As String, clickeventcolor As Int)

    Log("B4A : eventstartdatetime = " & eventstartdatetime)
    Log("B4A : clickeventname = " & clickeventname)
    Log("B4A : clickeventdetail = " & clickeventdetail)
    Log("B4A : clickeventcolor = " & clickeventcolor)

End Sub

To change the appearance:
B4X:
mdcv1.DefaultEventSelectColor = Colors.Yellow
mdcv1.DayOfMonthTextSize = 40
mdcv1.DayOfWeekTextSize = 25
mdcv1.TimeTextSize = 18
mdcv1.EventTextSize = 20

When you touch a cell with an Event that has been set it will display a Toast Message with the name of the Calendar Event and the Detail of the Calendar Event.

The Toast Message is displayed by making use of inline Java code. Therefor you also need to enable the JavaObject (v2.05) library in the IDE.

I will help/assist where I can to amend/change/modify the lib - but I am mostly leaving it up to you to take it further.

Sample code:

B4X:
#Region  Project Attributes
    #ApplicationLabel: MultiDayCalendarView
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: portrait
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

    Dim nativeMe As JavaObject

End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.

    Private mdcv1 As MultiDayCalendarView

End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("main")

    nativeMe.InitializeContext

    mdcv1.ClickEventName = "Morning Meeting"
    mdcv1.ClickEventDetail = "All Operations Personnel"
    mdcv1.ClickEventColor = Colors.DarkGray
    mdcv1.DefaultEventSelectColor = Colors.Yellow
    mdcv1.DayOfMonthTextSize = 40
    mdcv1.DayOfWeekTextSize = 25
    mdcv1.TimeTextSize = 18
    mdcv1.EventTextSize = 20  

End Sub

Sub Activity_Resume

    Dim tim As Long = DateTime.TimeZoneOffset * 60 * 60 * 1000
'    tim = tim + DateTime.Now  - DateTime.GetMinute(DateTime.Now) * 60 * 1000 - DateTime.GetSecond(DateTime.Now) * 1000
'    tim = tim/1000

    DateTime.DateFormat = "yyyy/MM/dd"
    DateTime.TimeFormat = "HH:mm:ss"

    tim = tim + DateTime.DateTimeParse("2016/04/18", "18:00:00")                  'tim = in milliseconds
    tim = tim/1000                                                                'tim = converted to seconds
    mdcv1.addEvent(tim, "Supper with John", "The Butcher Boys", Colors.Blue)      'seconds need to be passed
    'mdcv1.removeEvent(tim)                                                       'this will remove the same event that we have just set in the line above

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub mdcv1_event_selected(eventname As String, eventdetail As String)

    Log("B4A: calendar eventname = " & eventname)
    Log("B4A: calendar eventdetail = " & eventdetail)
    nativeMe.RunMethod("showToastMessage", Array(eventname & " : " & eventdetail))

End Sub

Sub mdcv1_calendar_scrolling(firstday As String)

    Log("B4A: first day = " & firstday)

End Sub


Sub mdcv1_event_added(eventstartdatetime As Long, clickeventname As String, clickeventdetail As String, clickeventcolor As Int)

    Log("B4A : eventstartdatetime = " & eventstartdatetime)
    Log("B4A : clickeventname = " & clickeventname)
    Log("B4A : clickeventdetail = " & clickeventdetail)
    Log("B4A : clickeventcolor = " & clickeventcolor)

End Sub


#If Java

import android.widget.Toast;

    //this will display a Toast Message (Event Name and Event Detail) when a cell containing an Event is touched
    public void showToastMessage(String message) {
        Toast.makeText(BA.applicationContext, message, Toast.LENGTH_SHORT).show();
    }

#End If

The library as it stands at present:

MultiDayCalendarView
Author:
Github: Sundeep Kahlon, Wrapped by: Johan Schoeman
Version: 1
  • MultiDayCalendarView
    Events:
    • calendar_scrolling (firstdateshown As String)
    • event_added (eventstartdatetime As Long, clickeventname As String, clickeventdetail As String, clickeventcolor As Int)
    • event_selected (eventname As String, eventdetail As String)
    Fields:
    • ba As BA
    Methods:
    • BringToFront
    • DesignerCreateView (base As PanelWrapper, lw As LabelWrapper, props As Map)
    • Initialize (EventName As String)
    • Invalidate
    • Invalidate2 (arg0 As Rect)
    • Invalidate3 (arg0 As Int, arg1 As Int, arg2 As Int, arg3 As Int)
    • IsInitialized As Boolean
    • RemoveView
    • RequestFocus As Boolean
    • SendToBack
    • SetBackgroundImage (arg0 As Bitmap)
    • SetColorAnimated (arg0 As Int, arg1 As Int, arg2 As Int)
    • SetLayout (arg0 As Int, arg1 As Int, arg2 As Int, arg3 As Int)
    • SetLayoutAnimated (arg0 As Int, arg1 As Int, arg2 As Int, arg3 As Int, arg4 As Int)
    • SetVisibleAnimated (arg0 As Int, arg1 As Boolean)
    • addEvent (seconds As Long, Eventname As String, detail As String, color As Int)
      Add an Event to the calendar
      The date and time converted to seconds (use the date and hour only - make minutes and seconds zero)
      Eventname = the name of the Event
      detail = the detail of the event
      color = the color of the cell that houses the Event
    • removeEvent (epochTimeInSecsToTheClosetHour As Long)
      Remove an Event from the Calendar
      epochTimeInSecsToTheClosetHour should be in "seconds"
    Properties:
    • Background As Drawable
    • ClickEventColor As Int [write only]
    • ClickEventDetail As String [write only]
    • ClickEventName As String [write only]
    • Color As Int [write only]
    • DayOfMonthTextSize As Int [write only]
      Default is 23
    • DayOfWeekTextSize As Int [write only]
      Default is 15
    • DefaultEventSelectColor As Int [write only]
      The color of an empty cell to chenge to when it is clicked on
      If you touch the same cell again an event will be added
      The event that will be added is based on what have been set with:
      ClickEventName = clickeventname,
      ClickEventDetail = clickeventdetail, and
      ClickEventColor = clickeventcolor
    • Enabled As Boolean
    • EventTextSize As Int [write only]
      Default is 13
    • Height As Int
    • Left As Int
    • Parent As Object [read only]
    • Tag As Object
    • TimeTextSize As Int [write only]
      Default is 13
    • Top As Int
    • Visible As Boolean
    • Width As Int

Sample pics:

SAMPLE B4A PROJECT STARTED
Started.png


AN EMPTY CELL TOUCHED - IT IS HIGHLIGHTED IN YELLOW
CellTouched.png



THE SAME YELLOW HIGHLIGHTED CELL TOUCED AGAIN. AN EVENT IS ADDED (MORNING MEETING)
SameCellTouchedAgain.png



CELL WITH AN EVENT TOUCHED - A TOAST MESSAGE IS DISPLAYED WITH THE EVENT NAME AND THE EVENT DETAIL (via inline Java Code)

ShowToastMessage.png


SCROLL LEFT USING YOUR FINGER (SEE THE B4A LOG)
ScrollLeft.png


SCROLL RIGHT USING YOUR FINGER (SEE THE B4A LOG)
ScrollRight.png



In order to compile the Java code you need to add a libs folder on the same folder lever as the src folder. Then copy android-support-v4.jar into the libs folder to compile the Java code to a jar and xml

DirectorySetup.png




Enjoy.....;)
 

Attachments

  • b4aMultiDayCalendarView.zip
    9 KB · Views: 585
  • MultiDayCalendarViewLibFiles.zip
    19.1 KB · Views: 575
  • TheJavaCode.zip
    51.5 KB · Views: 520
Last edited:

Roberto P.

Well-Known Member
Licensed User
Longtime User
I have problems at runtime, in the loading of the layout?
see image. what can it be?
thank you
 

Attachments

  • calendar.png
    calendar.png
    237.9 KB · Views: 280

Roberto P.

Well-Known Member
Licensed User
Longtime User
Updated, but I have the same problem!
 

Attachments

  • calendar.png
    calendar.png
    202.1 KB · Views: 260

Roberto P.

Well-Known Member
Licensed User
Longtime User
here is error:

main_activity_create (B4A line: 35)
Activity.LoadLayout("main")
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at anywheresoftware.b4a.keywords.LayoutBuilder.loadLayout(LayoutBuilder.java:166)
at anywheresoftware.b4a.objects.ActivityWrapper.LoadLayout(ActivityWrapper.java:209)
at JHS.MultiDayCalendarView.main._activity_create(main.java:375)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:169)
at JHS.MultiDayCalendarView.main.afterFirstLayout(main.java:103)
at JHS.MultiDayCalendarView.main.access$000(main.java:18)
at JHS.MultiDayCalendarView.main$WaitForLayout.run(main.java:81)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6134)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at anywheresoftware.b4a.objects.CustomViewWrapper.AfterDesignerScript(CustomViewWrapper.java:64)
at anywheresoftware.b4a.keywords.LayoutBuilder.loadLayout(LayoutBuilder.java:158)
... 16 more
Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v4/view/GestureDetectorCompat;
at main.java.com.github.sundeepk.multidaycalendarview.MultiDayCalendarView.init(MultiDayCalendarView.java:104)
at main.java.com.github.sundeepk.multidaycalendarview.MultiDayCalendarView.<init>(MultiDayCalendarView.java:85)
at main.java.com.github.sundeepk.multidaycalendarview.MultiDayCalendarView.<init>(MultiDayCalendarView.java:80)
at main.java.com.github.sundeepk.multidaycalendarview.MultiDayCalendarView.<init>(MultiDayCalendarView.java:76)
at multidaycalendarviewwrapper.multidayCalendarViewWrapper._initialize(multidayCalendarViewWrapper.java:60)
... 20 more
Caused by: java.lang.ClassNotFoundException: Didn't find class "android.support.v4.view.GestureDetectorCompat" on path: DexPathList[[zip file "/data/app/JHS.MultiDayCalendarView-1/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
... 25 more
Suppressed: java.lang.ClassNotFoundException: android.support.v4.view.GestureDetectorCompat
at java.lang.Class.classForName(Native Method)
at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
... 26 more
Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
 

Roberto P.

Well-Known Member
Licensed User
Longtime User
It works with addizional jar.
 

Roberto P.

Well-Known Member
Licensed User
Longtime User
but when I click on the cells from this error:

** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
B4A: first day = Mon Nov 28 01:00:00 CET 2016
B4A: first day = Mon Nov 28 01:00:00 CET 2016
B4A: first day = Mon Nov 28 01:00:00 CET 2016
B4A: first day = Tue Nov 29 01:00:00 CET 2016
B4A: first day = Wed Nov 30 01:00:00 CET 2016
B4A: first day = Wed Nov 30 01:00:00 CET 2016
B4A: first day = Wed Nov 30 01:00:00 CET 2016
B4A: first day = Wed Nov 30 01:00:00 CET 2016
B4A: first day = Tue Nov 29 01:00:00 CET 2016
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String main.java.com.github.sundeepk.multidaycalendarview.domain.Event.getEventName()' on a null object reference
at main.java.com.github.sundeepk.multidaycalendarview.MultiDayCalendarViewController.onLongPress(MultiDayCalendarViewController.java:120)
at main.java.com.github.sundeepk.multidaycalendarview.MultiDayCalendarView$1.onLongPress(MultiDayCalendarView.java:36)
at android.view.GestureDetector.dispatchLongPress(GestureDetector.java:700)
at android.view.GestureDetector.access$200(GestureDetector.java:40)
at android.view.GestureDetector$GestureHandler.handleMessage(GestureDetector.java:273)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6134)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
** Service (starter) Create **
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
B4A: first day = Sun Nov 27 01:00:00 CET 2016
B4A: first day = Sat Nov 26 01:00:00 CET 2016
B4A: first day = Fri Nov 25 01:00:00 CET 2016
B4A: first day = Thu Nov 24 01:00:00 CET 2016
B4A: first day = Wed Nov 23 01:00:00 CET 2016
B4A: first day = Tue Nov 22 01:00:00 CET 2016
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String main.java.com.github.sundeepk.multidaycalendarview.domain.Event.getEventName()' on a null object reference
at main.java.com.github.sundeepk.multidaycalendarview.MultiDayCalendarViewController.onLongPress(MultiDayCalendarViewController.java:120)
at main.java.com.github.sundeepk.multidaycalendarview.MultiDayCalendarView$1.onLongPress(MultiDayCalendarView.java:36)
at android.view.GestureDetector.dispatchLongPress(GestureDetector.java:700)
at android.view.GestureDetector.access$200(GestureDetector.java:40)
at android.view.GestureDetector$GestureHandler.handleMessage(GestureDetector.java:273)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6134)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
 

MAGAREY

Member
Licensed User
Longtime User
Is possible to increase the height of the cells of hours?

xL4JzaC.png
 
Last edited:
Top