Android Question Loading Your own Customview

stevenindon

Active Member
Licensed User
Hi all,

I have been creating a few of my own customview and find it a little weird as such :

This is the 'header' of my custom view

B4X:
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
    CallSubDelayed2(Me, "AfterLoadLayout", Props)
End Sub

Private Sub AfterLoadLayout(Props As Map)
    mBase.LoadLayout("Bar") '<<<---------------------LOADING FROM EXTERNAL .bal FORM
    mBase.Color=xui.Color_Transparent
End Sub


In my application starts up :

B4X:
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")
    Sleep(500)'<<---- DELAY DUE TO LOAD FORM FROM CUSTOM VIEW ???????
    '-----------------------------------------------------------------------------------------------------------
    TW_Bar1.TW_Init_View(2%x,4%x,20dip,5dip,1000)
    TW_Bar1.TW_CenterLabel1.Visible=True <<------ EXPOSED LABEL (Set as Public) IN CUSTOMVIEW

Note that when i call my customview, I HAVE to put a delay Sleep(500) before i can access to any exposed objects in my custom views. Else it will have error have error :
Object was not initialized (B4IPanelView)

The Sleep basically enables the 'mBase.LoadLayout("Bar")' to finish loaded before i can call any object INSIDE the customview

My question is :
1) Is this even the right way to of doing it?
2) How can i make do WITHOUT Sleep(500)
 

klaus

Expert
Licensed User
Longtime User
Sorry, but you do not give enough information.
The best way for us to help you, would be if you posted a small project showing the problem.
Object was not initialized (B4IPanelView)
What is B4IPanelView?
 
Upvote 0

stevenindon

Active Member
Licensed User
Thank you Klaus / LucaMs. Please find attached zip for my customview. Its basically a customview - which you can configure during onload to change its appearance.

I need to take out the Sleep(500)... as this sleep causes blank screen

Click : https://www.techiesworld.net/B4X_BAR.zip to download (** Creating this Customview for crosss platform - android/IOS)
 
Last edited:
Upvote 0

klaus

Expert
Licensed User
Longtime User
Sorry, but I do not really understand what exactly you want to do, it is very confusing, at leas for me.
You are mixing up CustomView and adding views in the code.
You are defining views in the CustomView with a layout.
Then you define others in the main code, very strange !?
You need to explain more in detail what exactly you want to do.
In my mind, everything you want to do in the CustomView should be done in the CustomView module.
If I understand well, it seems that you try to add the CustomView in the code.
If this is the case you could add a routine in the CustomView module as explained in the B4X Custom views booklet chapter 4.3 Adding a custom view by code.
Yes, I know, Erel does not like it, but it is possible.
 
Upvote 0

Omar Parra A.

Expert
Licensed User
Longtime User
I don't see the problem of loading the custom layout, and there is no reason to add Sleep(500) when loading the layout.

you example:

Custom View
Add Ready event:
B4X:
#Event: Click(svalue as String)
#Event: Ready

Sub Class_Globals
    Private mEventName As String 'ignore
    Private mCallBack As Object 'ignore
    Private mBase As B4XView
    Private PnlShadow As Panel
    Public TW_BackPanel As B4XView
    Public TW_BackImgView As B4XView
    Public TW_CenterLabel1 As B4XView
    Public TW_CenterLabel2 As B4XView
    Public TW_Button(10) As B4XView
    Public TW_SmallLabel(10) As B4XView
    Public TW_SmallImgView(10) As B4XView
    Public TW_TxtInput As B4XView
    Dim xui As XUI
    Private gRadius As Int=0
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
    CallSubDelayed2(Me, "AfterLoadLayout", Props)
End Sub

Private Sub AfterLoadLayout(Props As Map)
    mBase.LoadLayout("Bar")
    mBase.Color=xui.Color_Transparent
 
    If SubExists(mCallBack, mEventName & "_Ready") Then
        CallSub(mCallBack, mEventName & "_Ready")
    End If
End Sub

main page
Private Sub TW_Bar1_Ready
B4X:
#Region Shared Files
#CustomBuildAction: folders ready, %WINDIR%\System32\Robocopy.exe,"..\..\Shared Files" "..\Files"
'Ctrl + click to sync files: ide://run?file=%WINDIR%\System32\Robocopy.exe&args=..\..\Shared+Files&args=..\Files&FilesSync=True
#End Region

'Ctrl + click to export as zip: ide://run?File=%B4X%\Zipper.jar&Args=Project.zip

Sub Class_Globals
    Private Root As B4XView
    Private xui As XUI
    Private TW_Bar1 As TW_Bar
End Sub

Public Sub Initialize
    B4XPages.GetManager.TransitionAnimationDuration = 0
End Sub

Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")
End Sub

Private Sub TW_Bar1_Ready
    TW_Bar1.TW_Init_View(0%x,4%x,20dip,5dip,1000)
    TW_Bar1.TW_BackImgView_SetImage(LoadBitmap(File.DirAssets,"banner.jpg"))
    TW_Bar1.TW_BackImgView.Visible=True
    For x=0 To 4
        TW_Bar1.TW_SetButton_TextColor(TW_Bar1.TW_Button(x),xui.Color_White)
        TW_Bar1.TW_Button(x).Font=xui.CreateFontAwesome(30)
        TW_Bar1.TW_Button(x).Color=xui.Color_Transparent
        TW_Bar1.TW_Button(x).Visible=True
    Next
    TW_Bar1.TW_Button(0).Top=6%x
    TW_Bar1.TW_Button(0).Text=Chr(0xF039)
    TW_Bar1.TW_Button(1).Text=""
    TW_Bar1.TW_Button(2).Text=""
    TW_Bar1.TW_Button(3).Text=""
    TW_Bar1.TW_Button(4).Top=6%x
    TW_Bar1.TW_Button(4).Text=Chr(0xF013)
    '-----------------------------------------------------------------
    TW_Bar1.TW_CenterLabel1.left=20%x
    TW_Bar1.TW_CenterLabel1.Top=4%x
    TW_Bar1.TW_CenterLabel1.Height=14%x
    TW_Bar1.TW_CenterLabel1.Font=xui.CreateDefaultBoldFont(20)
    TW_Bar1.TW_CenterLabel1.Text="Malaysia zoologist"
    TW_Bar1.TW_CenterLabel1.Color=xui.Color_Transparent
    TW_Bar1.TW_CenterLabel1.TextColor=xui.Color_White
    TW_Bar1.TW_CenterLabel1.Visible=True
    '-----------------------------------------------------------------
    TW_Bar1.TW_CenterLabel2.Text="Welcome - Selamat Datang - 欢迎"
    TW_Bar1.TW_CenterLabel2.left=20%x
    TW_Bar1.TW_CenterLabel2.Top=14%x
    TW_Bar1.TW_CenterLabel2.TextSize=13
    TW_Bar1.TW_CenterLabel2.Color=xui.Color_Transparent
    TW_Bar1.TW_CenterLabel2.TextColor=xui.Color_Yellow
    TW_Bar1.TW_CenterLabel2.Visible=True
 
End Sub

See demo:
 
Last edited:
Upvote 0

stevenindon

Active Member
Licensed User
Klaus : Sorry for not explaining clearly what i wanted to achieve here. Basically i wanted to build a widget with some labels, Imageviews and buttons (10 each). When you place these widget to use, You can directly manipulate/change the properties of these labels from your code (text/height/top/... etc etc) as these labels , Imagesviews, buttons are assigned Public in the widget (Instead of me having to create that many properties under Props).

oparra : Thanks and its a brilliant idea of what you have done. Tested on android without problem.. but still i have problem using the same method for IOS.
In IOS, I have assigned it this way :


B4X:
Private Sub AfterLoadLayout(Props As Map)
    mBase.LoadLayout("Bar")
    mBase.Color=xui.Color_Transparent
    #if B4A
    If SubExists(mCallBack, mEventName & "_Ready") Then
        CallSub(mCallBack, mEventName & "_Ready")
    End If
    #Else if B4i
    If SubExists(mCallBack, mEventName & "_Ready",0) Then
        Sleep(200) <<------- (Without this delay, IOS wont work
        CallSub(mCallBack, mEventName & "_Ready")
    End If
    #End if
End Sub

I mean..in IOS it work.. but still need to place Sleep(200)
 
Upvote 0

Omar Parra A.

Expert
Licensed User
Longtime User
test: Sleep(0)
B4X:
Public Sub DesignerCreateView (Base As Panel, Lbl As Label, Props As Map)
    mBase = Base
    Sleep(0)
    CallSubDelayed2(Me, "AfterLoadLayout", Props)
End Sub

Private Sub AfterLoadLayout(Props As Map)
    mBase.LoadLayout("Bar")
    mBase.Color=xui.Color_Transparent
 
    If SubExists(mCallBack, mEventName & "_Ready") Then
        CallSub(mCallBack, mEventName & "_Ready")
    End If
End Sub
 
Upvote 0

Omar Parra A.

Expert
Licensed User
Longtime User
Klaus : Sorry for not explaining clearly what i wanted to achieve here. Basically i wanted to build a widget with some labels, Imageviews and buttons (10 each). When you place these widget to use, You can directly manipulate/change the properties of these labels from your code (text/height/top/... etc etc) as these labels , Imagesviews, buttons are assigned Public in the widget (Instead of me having to create that many properties under Props).

oparra : Thanks and its a brilliant idea of what you have done. Tested on android without problem.. but still i have problem using the same method for IOS.
In IOS, I have assigned it this way :


B4X:
Private Sub AfterLoadLayout(Props As Map)
    mBase.LoadLayout("Bar")
    mBase.Color=xui.Color_Transparent
    #if B4A
    If SubExists(mCallBack, mEventName & "_Ready") Then
        CallSub(mCallBack, mEventName & "_Ready")
    End If
    #Else if B4i
    If SubExists(mCallBack, mEventName & "_Ready",0) Then
        Sleep(200) <<------- (Without this delay, IOS wont work
        CallSub(mCallBack, mEventName & "_Ready")
    End If
    #End if
End Sub

I mean..in IOS it work.. but still need to place Sleep(200)
B4X:
Private Sub AfterLoadLayout(Props As Map)
    mBase.LoadLayout("Bar")
    mBase.Color=xui.Color_Transparent
    #if B4i
    Sleep(200)
    #End if
    If SubExists(mCallBack, mEventName & "_Ready") Then
        CallSub(mCallBack, mEventName & "_Ready")
    End If
End Sub
 
Upvote 0

stevenindon

Active Member
Licensed User
Klaus, Thank you for your effort. I think i need to change strategy... I guess still the most reliable way for this to work for both Android and IOS is to create properties in the CustomView.

B4X:
#DesignerProperty: Key: PnlShadow_top, DisplayName: PnlShadow Top, FieldType: Int, DefaultValue: 10, MinRange: 0, MaxRange: 1000
#DesignerProperty: Key: PnlShadow_leftright, DisplayName: PnlShadow LeftRight, FieldType: Int, DefaultValue: 10, MinRange: 0, MaxRange: 1000
#DesignerProperty: Key: PnlShadow_radius, DisplayName: PnlShadow Radius, FieldType: Int, DefaultValue: 10, MinRange: 0, MaxRange: 1000


I have lots to add ... Thank you again for finding out.

*Oh by the way.. above Sleep(0).. still does not work. Unless i put some sleep(200). Don't really know if it is because of my iPhone6 which is too old.
* Note for ios, SubExists(mCallBack, mEventName & "_Ready",0) <<----- there are additional parameter 0
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
Instead of:
SubExists(mCallBack, mEventName & "_Ready",0)
use
xui.SubExists(mCallBack, mEventName & "_Ready",0)
which is cross-platform.
 
Upvote 0

Omar Parra A.

Expert
Licensed User
Longtime User
B4X change:
Sub Class_Globals
Private mEventName As String 'ignore
Private mCallBack As Object 'ignore
Private mBase As B4XView
Private PnlShadow As Panel
Public TW_BackPanel As B4XView
Public TW_BackImgView As B4XView
Public TW_CenterLabel1 As B4XView
Public TW_CenterLabel2 As B4XView
Public TW_Button(10) As B4XView
Public TW_SmallLabel(10) As B4XView
Public Sub DesignerCreateView (Base As Panel, Lbl As Label, Props As Map)
mBase = Base
CallSubDelayed2(Me, "AfterLoadLayout", Props)
End Sub
etc, etc,

Use:
1639555588245.png
 
Upvote 0

stevenindon

Active Member
Licensed User
oparra, Thank you for above info. Will change all to Custom View(XUI) instead of still Custom View. That should be a good practice for multiplatform.

Thanks again
 
Upvote 0
Top