Hi everyone, I'm playing with creating a CustomView for the first time and I can't figure out how to communicate with it reliably.
The key thing I want to do at the moment is, at any time I want, pass a timestamp to my view and then have the view update the date field within it.
I tried creating a public "SetDate" method in the customview, which crashes out when I run it.
Here's the relevant parts of what I did:
CDDatePicker
(My custom view)
Then in my main activity, I have a button that when clicked, calls:
The SetDate function is invoked, however when the UpdateDisplay function within the CustomView is called, LblMonth is null, and pretty much everything in there is null.
Why is LblMonth null? And what is the correct way of working with custom views?
The error in full is:
** Service (starter) Create **
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
Error occurred on line: 168 (CDDatePicker)
java.lang.NullPointerException: expected receiver of type anywheresoftware.b4a.objects.TextViewWrapper, but got null
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:703)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:337)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:247)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:134)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:157)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:153)
at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:78)
at android.view.View.performClick(View.java:4240)
at android.view.View$PerformClick.run(View.java:17721)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
Any ideas?
The key thing I want to do at the moment is, at any time I want, pass a timestamp to my view and then have the view update the date field within it.
I tried creating a public "SetDate" method in the customview, which crashes out when I run it.
Here's the relevant parts of what I did:
CDDatePicker
(My custom view)
B4X:
Sub Class_Globals
Private EventName As String 'ignore
Private CallBack As Object 'ignore
Private Canvas As Panel
Private LblDate As Label
Private IVDownArrow As ImageView
Private DateFormatStr As String
Private LblMonth As Label
Private IVLeftArrowMonth As ImageView
Private IVRightArrowMonth As ImageView
Private LblDay As Label
Private IVLeftArrowDay As ImageView
Private IVRightArrowDay As ImageView
Private CurrentStamp As Long
Private Unfolded As Boolean = False
Private InitialHeight As Int
Private UnfoldedHeight As Int
Public CurrentHeight As Int
Dim ControlHeight As Int = 30dip
Dim ControlGapV As Int = 10dip
Dim MyTimer As Timer
End Sub
Public Sub DesignerCreateView (Base As Panel, Lbl As Label, Props As Map)
Canvas = Base
Canvas.Color = Props.Get("BackgroundColor")
Dim CurrentY As Int = 0
DateFormatStr = CDDatePickerStorage.DateFormat
DateTime.DateFormat = DateFormatStr
CurrentStamp = DateTime.Now
' Add Label to Show Current Date
LblDate.Initialize("LblDate")
LblDate.TextSize = CDDatePickerStorage.FontSize
LblDate.TextColor = Props.Get("ControlFontColor")
LblDate.Text = DateTime.Date(CurrentStamp)
LblDate.Gravity = Gravity.CENTER
Canvas.AddView(LblDate, 0, 0, Canvas.Width - 35dip, ControlHeight)
InitialHeight = ControlHeight
Canvas.Height = InitialHeight
IVDownArrow.Initialize("IVImageView")
Canvas.AddView(IVDownArrow, Canvas.Width - 30dip, 0, ControlHeight, ControlHeight)
RenderSVG(IVDownArrow, "i-down-arrow.svg", 1)
CurrentY = CurrentY + ControlHeight + ControlGapV
' DAY
' Add Label to Show Current Date
LblDay.Initialize("LblDay")
LblDay.Text = GetDayString(CurrentStamp)
LblDay.TextSize = CDDatePickerStorage.FontSize
LblDay.Gravity = Gravity.CENTER
LblDay.TextColor = Props.Get("ControlFontColor")
Canvas.AddView(LblDay, 35dip, CurrentY, Canvas.Width - 70dip, ControlHeight)
IVLeftArrowDay.Initialize("IVLeftArrowDay")
Canvas.AddView(IVLeftArrowDay, 0, CurrentY, ControlHeight, ControlHeight)
RenderSVG(IVLeftArrowDay, "i-left-arrow.svg", 1)
IVRightArrowDay.Initialize("IVRightArrowDay")
Canvas.AddView(IVRightArrowDay, Canvas.Width - 30dip, CurrentY, ControlHeight, ControlHeight)
RenderSVG(IVRightArrowDay, "i-right-arrow.svg", 1)
CurrentY = CurrentY + ControlHeight + ControlGapV
' MONTH
' Add Label to Show Current Date
LblMonth.Initialize("LblMonth")
LblMonth.Text = GetMonthName(DateTime.GetMonth(CurrentStamp))
LblMonth.TextSize = CDDatePickerStorage.FontSize
LblMonth.TextColor = Props.Get("ControlFontColor")
LblMonth.Gravity = Gravity.CENTER
Canvas.AddView(LblMonth, 35dip, CurrentY, Canvas.Width - 70dip, ControlHeight)
IVLeftArrowMonth.Initialize("IVLeftArrowMonth")
Canvas.AddView(IVLeftArrowMonth, 0, CurrentY, ControlHeight, ControlHeight)
RenderSVG(IVLeftArrowMonth, "i-left-arrow.svg", 1)
IVRightArrowMonth.Initialize("IVRightArrowMonth")
Canvas.AddView(IVRightArrowMonth, Canvas.Width - 30dip, CurrentY, ControlHeight, ControlHeight)
RenderSVG(IVRightArrowMonth, "i-right-arrow.svg", 1)
CurrentY = CurrentY + ControlHeight + ControlGapV
UnfoldedHeight = CurrentY
CDDatePickerStorage.PickerHeight = UnfoldedHeight
If((Props.ContainsKey("ControlFont")) And (Props.Get("ControlFont") <> "")) Then
Try
Dim Const StandardFont As Typeface = Typeface.CreateNew(Typeface.LoadFromAssets(Props.Get("ControlFont")), Typeface.STYLE_BOLD)
LblDate.Typeface = StandardFont
LblMonth.Typeface = StandardFont
LblDay.Typeface = StandardFont
Catch
Log(LastException)
End Try
End If
MyTimer.Initialize("MyTimer", 500)
MyTimer.Enabled = True
End Sub
Public Sub UpdateDisplay
LblMonth.Text = GetMonthName(DateTime.GetMonth(CurrentStamp))
LblDay.Text = GetDayString(CurrentStamp)
Log("Setting to stamp: " & DateTime.Date(CurrentStamp))
DateTime.DateFormat = DateFormatStr
LblDate.Text = DateTime.Date(CurrentStamp)
If(SubExists(CallBack, EventName & "_DateChanged")) Then
CallSub2(CallBack, EventName & "_DateChanged", CurrentStamp)
End If
End Sub
Public Sub SetDate(Ticks As Long)
CurrentStamp = Ticks
UpdateDisplay
End Sub
Then in my main activity, I have a button that when clicked, calls:
B4X:
Sub BtnNow_Click
DatePicker.SetDate(DateTime.Now)
End Sub
The SetDate function is invoked, however when the UpdateDisplay function within the CustomView is called, LblMonth is null, and pretty much everything in there is null.
Why is LblMonth null? And what is the correct way of working with custom views?
The error in full is:
** Service (starter) Create **
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
Error occurred on line: 168 (CDDatePicker)
java.lang.NullPointerException: expected receiver of type anywheresoftware.b4a.objects.TextViewWrapper, but got null
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:703)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:337)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:247)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:134)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:157)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:153)
at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:78)
at android.view.View.performClick(View.java:4240)
at android.view.View$PerformClick.run(View.java:17721)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
Any ideas?
Last edited: