Android Question LoadLayout FirstTime

ttsolution

Member
Licensed User
Longtime User
Dear all,

What is difference with LoadLayout at every time Activity Created and just for the FirstTime? I ask this question because sometime error occur said that some Label not Initialized (but these Labels are in the Layout file)

Sub Activity_Create(FirstTime As Boolean)
Activity.LoadLayout("Order")​
End Sub

Sub Activity_Create(FirstTime As Boolean)
If FirstTime Then
Activity.LoadLayout("Order")​
End If​
End Sub

Regards,

Jonh
 

eurojam

Well-Known Member
Licensed User
Longtime User
Loading the layout will initialize the views, labels.... If your Activity is not active and may be destroyed in the background for memory reasons, your Labels and other views will not be initialized in the resume process .... that's my understanding of this. May be the b4a experts know it better;-)

good luck
stefan
 
Upvote 0

udg

Expert
Licensed User
Longtime User
Hi John,

my understanding is that the key point is that var FirstTime refers to the process not to the activity.
That means you may re-enter an Activity where its process is still alive in memory and that will give you a FirstTime = False instead of the True value you expect.

udg
 
Upvote 0

ttsolution

Member
Licensed User
Longtime User
Many thanks for your inputs. My concern is :what problem if I LoadLayout everytime the Activity is activated (bring to front). I have tested, it run well but I do not know if it may consume more memory or not

Regards,

Jonh
 
Upvote 0

corwin42

Expert
Licensed User
Longtime User
A LoadLayout() call does not replace the views that are currently on the Activity but they are added.
So if you call LoadLayout() multiple times with the same layout you will end up with multiple copies of the views.
 
Upvote 0

ttsolution

Member
Licensed User
Longtime User
Thanks corwin42.

The first time I open this Activity is OK. But from the second time onward when I open this Activity I got the error message "Object should be first initialized (ListView)". But The ListView lstCustomer is in the Layout file. I do not know why. My current solution is load the Layout file everytime the Activity is activated (bring to front) and this can creates multi duplicated views as your notes.

Many thanks for any help.

Jonh.

B4X:
Sub Process_Globals
    Public mType As String=""
End Sub

Sub Globals
    Dim lstCustomer As ListView
    Private cmdBack As Button
End Sub

Sub Activity_Create(FirstTime As Boolean)
    If FirstTime Then
        Activity.LoadLayout("frmDailyCustomer")
    End If
End Sub

Sub Activity_Resume
    LoadCustomer
End Sub

Sub Activity_Pause (UserClosed As Boolean)
End Sub

Sub LoadCustomer()
    Dim strSQL As String
    Dim Cursor1 As Cursor
    Dim mTypeName As String=""
    Dim bmp As Bitmap
    bmp = LoadBitmap(File.DirAssets, "Positioned.png")
  
    ProgressDialogShow("Loading Customers...")
    'If lstCustomer.IsInitialized=False Then lstCustomer.Initialize("lstCustomer")
  
    lstCustomer.Clear
  
    mainModule.FormatListView(lstCustomer,14,13)
  
    Select mType
        Case "COMPLETE"
            strSQL="Select ifnull(Dist,999) as Dist, LAT,LON,CustomerId,CustomerName,FullAddress,Ifnull(LastCheckIn,0) as LastCheckIn from Customers Where(Ifnull(LastCheckIn,0)>0) And (Ifnull(Cancelled,0)=0) And (DailyRoute='Y') And (ifnull(CallUploaded,0)=1) Order by CustomerName"
            mTypeName="Khách hàng đã upload"
        Case "ACTIVE"
            strSQL="Select ifnull(Dist,999) as Dist,LAT,LON,CustomerId,CustomerName,FullAddress,Ifnull(LastCheckIn,0) as LastCheckIn from Customers Where(Ifnull(LastCheckIn,0)>0) And (Ifnull(Cancelled,0)=0) And (DailyRoute='Y') And (ifnull(CallUploaded,0)=0) Order by CustomerName"
            mTypeName="Khách hàng chưa upload"
        Case "CANCELLED"
            strSQL="Select ifnull(Dist,999) as Dist,LAT,LON,CustomerId,CustomerName,FullAddress,Ifnull(LastCheckIn,0) as LastCheckIn from Customers Where(Ifnull(Cancelled,0)=1) And (DailyRoute='Y') Order by CustomerName"
            mTypeName="Khách hàng hủy viếng thăm"
        Case "PENDING"
            strSQL="Select ifnull(Dist,999) as Dist,LAT,LON,CustomerId,CustomerName,FullAddress,Ifnull(LastCheckIn,0) as LastCheckIn from Customers Where(Ifnull(Cancelled,0)=0) And (DailyRoute='Y') And (Ifnull(CallUploaded,0)=0) And (Ifnull(LastCheckIn,0)=0) Order by Idx"
            mTypeName="Khách chưa viếng thăm"
    End Select
  
    Cursor1 = Main.SQL1.ExecQuery(strSQL)
    If Cursor1.RowCount>0 Then
        For i = 0 To Cursor1.RowCount - 1
            Cursor1.Position = i

            Dim O As Customer
            O.CustomerName=Cursor1.GetString("CustomerName")
            O.CustomerId=Cursor1.GetLong("CustomerId")
            O.LAT=Cursor1.GetDouble("LAT")
            O.LON=Cursor1.GetDouble("LON")
          
            If (Cursor1.GetDouble("LAT")>0) OR (Cursor1.GetDouble("LON")>0) Then
                lstCustomer.AddTwoLinesAndBitmap2(O.CustomerName,Cursor1.GetString("FullAddress"),bmp,O)
            Else
                lstCustomer.AddTwoLines2(O.CustomerName,Cursor1.GetString("FullAddress"),O)
            End If
        Next
    Else
        Cursor1.Close
        ProgressDialogHide
        Activity.Finish
    End If
  
    Cursor1.Close
    ProgressDialogHide
  
    Activity.Title=mTypeName & " (" & Cursor1.RowCount & ")"
End Sub
  
Sub lstCustomer_ItemClick (Position As Int, Value As Object)
    Dim C As Customer=Value
    If mType="CANCELLED" Then
        If mainModule.NzNum(Main.SQL1.ExecQuerySingleResult("Select Ifnull(RouteClosed,0) from Sys"))<>1 Then
            actUnCancel.mCustomerId=C.CustomerId
            actUnCancel.mCustomerName=C.CustomerName
            StartActivity(actUnCancel)
        End If
    Else
        actProcess.mCustomerId=C.CustomerId
        actProcess.mCustomerName=C.CustomerName
        StartActivity(actProcess)  
    End If
End Sub

Sub cmdBack_Click
    Activity.Finish
End Sub
 
Last edited:
Upvote 0

NJDude

Expert
Licensed User
Longtime User
A couple of things, first, PLEASE, use the [code]...[/code] tags when posting code, second, you should not load the layout when "If FirstTime" if you do that it means the layout will load ONLY the VERY FIRST TIME you run the app.
 
Upvote 0

ttsolution

Member
Licensed User
Longtime User
Thanks NJDude. May I do as the following

B4X:
Sub Activity_Create(FirstTime As Boolean)
    Activity.RemoveAllViews
    Activity.LoadLayout("DownloadMasterList")
End Sub
 
Upvote 0

ttsolution

Member
Licensed User
Longtime User
Refer to corwin42's notes, if I call LoadLayout() multiple times with the same layout will end up with multiple copies of the views.
 
Upvote 0

corwin42

Expert
Licensed User
Longtime User
Refer to corwin42's notes, if I call LoadLayout() multiple times with the same layout will end up with multiple copies of the views.

You should carefully read (and understand) the Android Activity Lifecycle Tutorial again. This is in my opinion the most important B4A tutorial at all.
Another very helpful resource is the Lifecycle diagram.

So my statement is correct. If you call LoadLayout() multiple times as long as the Activity "lives" then all the views in the layout are added again and again.
But NJDude is also correct because Activity_Create() is only called when the Activity gets created. So if it just gets created it is empty and we should load the layout here and don't need to remove anything from it.

It is important to understand the difference between the process and the activity. The "LoadLayout() only when FirstTime is true" mistake is very common. Another very common mistake is that developers think that the main Activity is always the first one started and do their initializations only there.
This quiz and the first few posts is a good explanation of some of the most common mistakes done in B4A development.
 
Upvote 0
Top