Android Question [Closed] Reusing layout, how to reuse/factor related code?

Alexis Martial

Member
Licensed User
Layout and their scripts are fantastic!

In my current application, I have such a layout that is actually for an overlay/dialog and I'm reusing it in 2 activities.

However, I can't find a way to reuse the code that handle them (filling the fields, handling the events, etc).

I could write a dedicated module but can't use Designer to declare the different views into this module.
I could pass the enclosing panel to each of this module routine, but that means I would have to manually find each child view [which I guess is what B4A is doing behind the scene].
Issue is this make it very difficult to maintain.

Any suggestion for those that have done similar things?
 

Alexis Martial

Member
Licensed User
You may have a look at the B4X Custom Views Booklet.
Thanks,

I went through it and various examples and they are running fine when I compiled them.

I still didn't manage to make mine works.
I stripped down my code to the minimum.
Basically my custom view is now just loading a layout.
I tried with CustomView and CustomView XUI without success :-(

Stripped down code of my custom view:

B4X:
Sub Class_Globals
    Private mEventName As String 'ignore
    Private mCallBack As Object 'ignore
    Private mBase As Panel
    Private Button1 As Button
End Sub

Public Sub Initialize (Callback As Object, EventName As String)
    mEventName = EventName
    mCallBack = Callback
End Sub

Public Sub DesignerCreateView (Base As Panel, Lbl As Label, Props As Map)
    mBase = Base
    mBase.LoadLayout("Basic")
End Sub
the Layout "Basic" only include one button since I wanted to test with the simplest case.

My Custom view Initialize and DesignerCreateView methods are called [I put breakpoints there]
But the call to LoadLayout fails with:

Error occurred on line: 56 (QRCodeSummaryView)
java.lang.RuntimeException: java.lang.ClassCastException: sg.com.idigo.pokeelite.b4xtable cannot be cast to android.widget.TextView
at anywheresoftware.b4a.keywords.LayoutBuilder.loadLayout(LayoutBuilder.java:170)
at anywheresoftware.b4a.objects.PanelWrapper.LoadLayout(PanelWrapper.java:134)
...

And I can't understand where the "sg.com.idigo.pokeelite.b4xtable cannot be cast to android.widget.TextView" come from !
Note that I have a B4XTable in the main activity layout that include my custom view, but I can't see how they relate.

Any clues will be much then welcome !
 

Alexis Martial

Member
Licensed User
Another interesting thing is part of the error list below the ones I already included:
...
Caused by: java.lang.ClassCastException: sg.com.idigo.pokeelite.b4xtable cannot be cast to android.widget.TextView
at anywheresoftware.b4a.objects.CustomViewWrapper.AfterDesignerScript(CustomViewWrapper.java:44)
at anywheresoftware.b4a.keywords.LayoutBuilder.loadLayout(LayoutBuilder.java:162)
... 34 more
 

Alexis Martial

Member
Licensed User
I did another test, using this customview in another activity, I got similar error, but this time not related to B4XTable:
java.lang.RuntimeException: java.lang.ClassCastException: java.lang.String cannot be cast to android.widget.TextView

So I guess I'm missing something very basic
 

klaus

Expert
Licensed User
You should post your test project so we can see what exactly you have done and find the probelm.
 

Alexis Martial

Member
Licensed User
Find attached.
Simplified to the max.

Main Activity load "Main" layout which include a panel that manually load "SubLayout" layout without issue, than the LoadLayoutCustomView that is supposed to load the same layout but fail with similar exception/error I faced in my full project.

Thanks so much for your help !
 

Attachments

klaus

Expert
Licensed User
Change your code to:
B4X:
'Base type must be Object
Public Sub DesignerCreateView (Base As Object, Lbl As Label, Props As Map)
    mBase = Base
 
    CallSubDelayed(Me, "LoadLayout")
 End Sub

Private Sub Base_Resize (Width As Double, Height As Double)
 
End Sub

Private Sub LoadLayout
    mBase.LoadLayout("SubLayout")
End Sub
It's the first time that I loaded a Layout in a CustomView.
I found the solution searching the forum in this thread: CustomView-Library with LoadLayout ?
In the project below, I changed a bit the SubLayout to see what happens.
 

Attachments

Last edited:

Alexis Martial

Member
Licensed User
So it's a timing/initialization order related stuff.
Let me apply this ASAP to my real project ;-)

Thanks again.

PS: is there a way to contribute to both Erel and you work on B4X ?
 

Erel

Administrator
Staff member
Licensed User
It is a bit simpler to use Sleep:
B4X:
Public Sub DesignerCreateView (Base As Object, Lbl As Label, Props As Map)
    mBase = Base
   Sleep(0)
    mBase.LoadLayout("SubLayout")
 End Sub
 

MarkusR

Well-Known Member
Licensed User
there was also a way to load a layout in a class and get the events there.

your class "MyClass"
B4X:
Sub Class_Globals
    Private xui As XUI
    
    'Private ButtonSave As B4XView
End Sub

Public Sub Initialize(Parent As B4XView)
     
    Parent.LoadLayout("YourLayout")
        
End Sub

'Sub ButtonSave_Click
   
 '  Log("ButtonSave_Click")

'End Sub
used in a activity
B4X:
Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
    Dim MyClass1 As MyClass

End Sub

Sub Activity_Create(FirstTime As Boolean)

   MyClass1.Initialize(Activity)

End Sub
 

klaus

Expert
Licensed User
The option of MarkusR is not for a CustomView.
The signature of the Initialize routine for a CustomView is:
Public Sub Initialize (Callback As Object, EventName As String)
 
Top