Android Question [SOLVED] B4XPage_Appear does not show correct variable value in a Reuse Page ?

incendio

Well-Known Member
Licensed User
Longtime User
Hi guys,

I have pgUtils that called by multiple pages.

Here are the codes from pgUtils
B4X:
Sub Class_Globals
    Private Root As B4XView 'ignore
    Private xui As XUI 'ignore
    Private PgMsg As String
End Sub

Public Sub Initialize(Msg As String) As Object
    PgMsg = Msg
    Return Me
End Sub

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

Sub B4XPage_Appear
    xui.MsgboxAsync(PgMsg, "B4X")
End Sub

Calling from page1
B4X:
Private Sub Button1_Click
    pageutil.Initialize("this is from page1")
    
    If B4XPages.GetManager.FindPIFromB4XPage(pageutil) = Null Then
        B4XPages.AddPage("pageutil",pageutil)
    End If
    
    B4XPages.ShowPage("pageutil")
End Sub

Calling from page2
B4X:
Private Sub Button1_Click
    pageutil.Initialize("this is from page2")
    
    If B4XPages.GetManager.FindPIFromB4XPage(pageutil) = Null Then
        B4XPages.AddPage("pageutil",pageutil)
    End If
    
    B4XPages.ShowPage("pageutil")
End Sub

If for the first time, pgutils called from page1, then called again from page2, variable PgMsg still hold a value from page1, though in sub Initialize already changed. Even after the app closed, variable PgMsg still hold value from the first caller. I have to forced close app to reset it.

Where is the problem?

Attached is the sample project.
 

Attachments

  • Pages.zip
    14.8 KB · Views: 5

William Lancee

Well-Known Member
Licensed User
Longtime User
Essentially you are initializing pageutil twice.
It is best if all pages are added to the B4XPageManager in B4XMainPage.
Since there is only one instance of "pageutil", you need another way to "set" the message (other than "initialize"). See below.

B4X:
'In MainPage
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")
    B4XPages.AddPage("pageutil",pageutil)

    pageutil.initialize
    page1.Initialize(pageutil)
    page2.Initialize(pageutil)
    B4XPages.AddPage("page1",page1)
    B4XPages.AddPage("page2",page2)
End Sub

B4X:
'in p1 and p2
Sub Class_Globals
    Private Root As B4XView 'ignore
    Private xui As XUI 'ignore
    Private pageutil As pgUtils
End Sub

Public Sub Initialize(pageUtils_ As pgUtils) As Object
    pageutil = pageUtils_
    Return Me
End Sub

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

Private Sub Button1_Click
    pageutil.Msg = "this is from page1"
    B4XPages.ShowPage("pageutil")
End Sub

B4X:
'In pageutil
Sub Class_Globals
    Private Root As B4XView 'ignore
    Private xui As XUI 'ignore
    Private PgMsg As String
End Sub

Public Sub Initialize As Object
    Return Me
End Sub

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

Public Sub setMsg(msg As String)
    PgMsg = msg
End Sub

Sub B4XPage_Appear
    xui.MsgboxAsync(PgMsg, "B4X")
End Sub
 
Upvote 0

incendio

Well-Known Member
Licensed User
Longtime User
Essentially you are initializing pageutil twice.
It is best if all pages are added to the B4XPageManager in B4XMainPage.
Since there is only one instance of "pageutil", you need another way to "set" the message (other than "initialize"). See below.

B4X:
'In MainPage
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")
    B4XPages.AddPage("pageutil",pageutil)

    pageutil.initialize
    page1.Initialize(pageutil)
    page2.Initialize(pageutil)
    B4XPages.AddPage("page1",page1)
    B4XPages.AddPage("page2",page2)
End Sub

B4X:
'in p1 and p2
Sub Class_Globals
    Private Root As B4XView 'ignore
    Private xui As XUI 'ignore
    Private pageutil As pgUtils
End Sub

Public Sub Initialize(pageUtils_ As pgUtils) As Object
    pageutil = pageUtils_
    Return Me
End Sub

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

Private Sub Button1_Click
    pageutil.Msg = "this is from page1"
    B4XPages.ShowPage("pageutil")
End Sub

B4X:
'In pageutil
Sub Class_Globals
    Private Root As B4XView 'ignore
    Private xui As XUI 'ignore
    Private PgMsg As String
End Sub

Public Sub Initialize As Object
    Return Me
End Sub

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

Public Sub setMsg(msg As String)
    PgMsg = msg
End Sub

Sub B4XPage_Appear
    xui.MsgboxAsync(PgMsg, "B4X")
End Sub
Thanks for your hints.

So this b4xpages is different from standard class where on standard class, initialize created new instance while B4Xpages only created it once. To reuse a page, I need a reference to that page in order to change its parameters.

I made pgutils to be public In B4XMainPage
B4X:
Sub Class_Globals
    Private Root As B4XView
    Private xui As XUI
    Private page1 As pg1
    Private page2 As pg2
    Public pageutils As pgUtils
End Sub

Public Sub Initialize
'    B4XPages.GetManager.LogEvents = True
End Sub

'This event will be called once, before the page becomes visible.
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")
    page1.Initialize
    page2.Initialize
    pageutils.Initialize
    
    B4XPages.AddPage("page1",page1)
    B4XPages.AddPage("page2",page2)
    B4XPages.AddPage("pageutil",pageutils)
End Sub

and on pg1/pg2, changed its parameters like this
B4X:
Private Sub Button1_Click
    B4XPages.MainPage.pageutils.Msg = "this is from page1"
    B4XPages.ShowPage("pageutil")
End Sub
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
While B4XPages are standard classes with all the same features, there should only be one instance of that class, since the B4XManager has registered that instance and any reference through B4Xpages (.ShowPage, .AddPage, etc.) only references the first registered instance. Further attempts at registering other instances fail with a warning message.

Making the 'utilities B4XPage instance' public in Mainpage is a one approach that works well.
 
Upvote 0
Top