Android Tutorial Two activities example

An improved version, based on CallSubDelayed is available here.
This example demonstrates how to work with more than one activity and how to pass information between the activities.
In this example we have two activities. One activity is the "main" activity. When the user presses a button a "list" activity will be displayed. The user will choose an item from the list and then return to the main activity:

two_activities.png



It is recommended that you first read the Activities life cycle tutorial if you haven't read it before.

In order to add a new or existing activity to your project you should choose Project - Add New / Existing Module.

Variables declared in Sub Process_Globals are public variables and can be accessed from other activities. Therefore we will save the chosen value in such a variable.

When the user presses on the "choose item" button we open the second activity:
B4X:
Sub Button1_Click
    StartActivity(Activity2)
End Sub
When we open an activity the current one is first paused and then the target activity is resumed (and created if needed).
You can see it in the logs:

twoactivities_logcat.png


The second activity is pretty simple:
B4X:
Sub Process_Globals
    Dim result As String
    result = ""
End Sub

Sub Globals
    Dim ListView1 As ListView
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("2")
    For i = 1 To 100
        ListView1.AddSingleLine("Item #" & i)
    Next
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub ListView1_ItemClick (Position As Int, Value As Object)
    result = value 'store the value in the process global object.
    StartActivity(Main) 'show the main activity again
End Sub
When the user presses on an item we store the value in the 'result' variable and we return to the main activity.

The main activity Resume event will be raised. So in this event we check if 'result' variable is not empty and change the label's text.
B4X:
Sub Activity_Resume
    If Activity2.result.Length > 0 Then
        Label1.Text = "You have chosen: " & Activity2.result
    Else
        Label1.Text = "Please press on the button and choose an item."
    End If
End Sub
In more complex applications with more than two activities you can use a process global variable in the main activity. Before starting an activity you can set this variable to some constant and then in Sub Activity_Resume check the value of this variable to know which activity was started and act accordingly.

The project is attached.
 

Attachments

  • TwoActivities.zip
    6.7 KB · Views: 6,093

margret

Well-Known Member
Licensed User
Longtime User
Panel Issue

You need to send the Panel (not its name) to your sub, for example if your panel is called pnlMyInput:
B4X:
PanelPop(pnlMyInput,"Layout File.bal", 0, 0)
'Last two parameters are panel offsets to change screen posistion


Sub PanelPop ( panelname, mlayout, hc, wc )
   pnlSelect.Initialize ( "Select")      
   pnlInput.Initialize ("")
   pnlInput.LoadLayout ( mlayout )    
   pnlSelect.Color  = Colors.ARGB (150,0,0,0)         
   Activity.AddView (pnlSelect, 0, 0,   100%x, 100%y)   
   mh1=(pnlSelect.Height/2) - ([B]panelname[/B].Height/2) + hc
   mw1=pnlSelect.Width/2 - ([B]panelname[/B].Width/2) + wc
   mh2=[B]panelname[/B].Height
   mw2=[B]panelname[/B].Width
   pnlSelect.AddView (pnlInput, mw1, mh1, mw2, mh2)
   'Example: edittexturl.Text=HomePage
End Sub

But there are four places that the panels name must be, as indicated in bold above. If you have to use the panel variable name, how does it get passed to the four positions that need it. As I stated I want this code to work for how every many panels I wish to popup and to not replicate this code for each. I will try what you said. I am changing the code and will report back. The error listed below is what you get when you send the panel to the sub. Looks like the only way it will work is to send the panel name and then have it macro substituted.

Compiling code. Error
Error compiling program.
Error description: Unknown member: height
Occurred on line: 376
mh1=(pnlSelect.Height/2) - (panelname.Height/2) + hc
Word: height

Thanks,

Margret
 
Last edited:

kickaha

Well-Known Member
Licensed User
Longtime User
No, there are 4 places where the Panel should be, hence send the panel.

As an aside, it is good practice to tell the sub what types it is receiving:
B4X:
Sub PanelPop ( panelname As Panel, mlayout As String, hc As Int, wc As Int)

That way, when you type in the subs name you are reminded what you should be sending, and the sub does not default everything to strings.
 

margret

Well-Known Member
Licensed User
Longtime User
Panel Issues

No, there are 4 places where the Panel should be, hence send the panel.

As an aside, it is good practice to tell the sub what types it is receiving:
B4X:
Sub PanelPop ( panelname As Panel, mlayout As String, hc As Int, wc As Int)

That way, when you type in the subs name you are reminded what you should be sending, and the sub does not default everything to strings.

I did as you said and the program complied fine. Then I loaded in the tablet and when you run the code to pop up the panel, I get the error that Object should be initialized (Panel).

If there were options for macros this would be done. But I understand that option is not in B4A, so, any ideas of how to make this work?

Thanks,

Margret
 

kickaha

Well-Known Member
Licensed User
Longtime User
Is the Panel that you are sending it initialized in code before you call this sub?

The sub should work, can you single step through it with the debugger and let us know what value panelname has got?
 

kickaha

Well-Known Member
Licensed User
Longtime User
Also, the panel you are sending to the sub needs to be added to a layout first, otherwise height and width make no sense!
 

margret

Well-Known Member
Licensed User
Longtime User
Panel Issues

Also, the panel you are sending to the sub needs to be added to a layout first, otherwise height and width make no sense!

If I change the name in four places that was marked bold from panelname to panelweb(panelweb is the real name of the panel in the layout file) the code runs fine and bring up the panel and all works just as it should. This ignores the panelname parameter passed to the sub, but everything works. Under sub globals I have Dim panelweb As Panel. This is driving me crazy. I felt like I was moving through this pretty good and then brick wall.

Thanks,

Margret
 
Last edited:

kickaha

Well-Known Member
Licensed User
Longtime User
Is panelweb in the layout you are sending to the sub (mlayout)? If it is, is it the only panel on the layout(s) that you want to pop up?
 

margret

Well-Known Member
Licensed User
Longtime User
Panel Issue

Is panelweb in the layout you are sending to the sub (mlayout)? If it is, is it the only panel on the layout(s) that you want to pop up?

Yes it is in the layout file I'm sending (mlayout) and yes, it is the only panel to display and the only panel in the layout file, the .bal. You have the code sniplet, and I was going to attached the layout file in a zip but this forum will not upload the zip file. If you PM me I will email the zip file with the layout.

Thanks,

Margret
 

kickaha

Well-Known Member
Licensed User
Longtime User
Try this, it will work if the layout only has one Panel on it. Note you do not need to send the panel to PanelPop as it finds it now.

B4X:
Sub PanelPop (mlayout As String, hc As Int, wc As Int)
   Dim panelname As Panel
   Dim out As Boolean : out = False
   Dim pointer As Int : pointer = 0

   pnlSelect.Initialize ( "Select")      
   pnlInput.Initialize ("")
   pnlInput.LoadLayout ( mlayout ) 
   
   Do While out = False
      If pnlInput.GetView (pointer) Is Panel Then
         out = True
         panelname = pnlInput.GetView (pointer)
      Else
         pointer = pointer + 1
         If pointer = pnlInput.NumberOfViews Then out = True
      End If
   Loop
   if pointer = pnlInput.NumberOfViews Then Return' error has occured no panel found
   pnlSelect.Color  = Colors.ARGB (150,0,0,0)         
   Activity.AddView (pnlSelect, 0, 0,   100%x, 100%y)   
   mh1=(pnlSelect.Height/2) - (panelname.Height/2) + hc
   mw1=pnlSelect.Width/2 - (panelname.Width/2) + wc
   mh2=panelname.Height
   mw2=panelname.Width
   pnlSelect.AddView (pnlInput, mw1, mh1, mw2, mh2)
   'Example: edittexturl.Text=HomePage
End Sub
 

margret

Well-Known Member
Licensed User
Longtime User
Panel Issue

Try this, it will work if the layout only has one Panel on it. Note you do not need to send the panel to PanelPop as it finds it now.

B4X:
Sub PanelPop (mlayout As String, hc As Int, wc As Int)
   Dim panelname As Panel
   Dim out As Boolean : out = False
   Dim pointer As Int : pointer = 0

   pnlSelect.Initialize ( "Select")      
   pnlInput.Initialize ("")
   pnlInput.LoadLayout ( mlayout ) 
   
   Do While out = False
      If pnlInput.GetView (pointer) Is Panel Then
         out = True
         panelname = pnlInput.GetView (pointer)
      Else
         pointer = pointer + 1
         If pointer = pnlInput.NumberOfViews Then out = True
      End If
   Loop
   if pointer = pnlInput.NumberOfViews Then Return' error has occured no panel found
   pnlSelect.Color  = Colors.ARGB (150,0,0,0)         
   Activity.AddView (pnlSelect, 0, 0,   100%x, 100%y)   
   mh1=(pnlSelect.Height/2) - (panelname.Height/2) + hc
   mw1=pnlSelect.Width/2 - (panelname.Width/2) + wc
   mh2=panelname.Height
   mw2=panelname.Width
   pnlSelect.AddView (pnlInput, mw1, mh1, mw2, mh2)
   'Example: edittexturl.Text=HomePage
End Sub

The problem is that this screen layout only has one. The other layouts I have has more than one panel to group different sets of radio buttons. I did not see where you could just add a container. Now the debugger has stopped working with no errors, the only thing I did was add some libraries. I try to start in debug mode and it just closes and with no errors. I get the same on the AVD. I spent the time to setup a new machine, fresh install and it does the same thing.
 

kickaha

Well-Known Member
Licensed User
Longtime User
I have just had a thought, is the panel you are getting the size of ONLY there to define the size of the pop-up on each layout?

If that is the case, give them the same name ON EVERY LAYOUT.

This will work, as the code will reference the last defined one when you invoke it. If we name them all sizepanel your code would then be
B4X:
Sub PanelPop (mlayout As String, hc As Int, wc As Int)

   pnlSelect.Initialize ( "Select")      
   pnlInput.Initialize ("")
   pnlInput.LoadLayout ( mlayout ) 
   pnlSelect.Color  = Colors.ARGB (150,0,0,0)         
   Activity.AddView (pnlSelect, 0, 0,   100%x, 100%y)   
   mh1=(pnlSelect.Height/2) - (sizepanel.Height/2) + hc
   mw1=pnlSelect.Width/2 - (sizepanel.Width/2) + wc
   mh2=sizepanel.Height
   mw2=sizepanel.Width
   pnlSelect.AddView (pnlInput, mw1, mh1, mw2, mh2)
   'Example: edittexturl.Text=HomePage
End Sub
Do not forget to Dim it in globals!

Sorry, can offer no help on the debugger.
 

margret

Well-Known Member
Licensed User
Longtime User
Panel Issue

I have just had a thought, is the panel you are getting the size of ONLY there to define the size of the pop-up on each layout?

If that is the case, give them the same name ON EVERY LAYOUT.

This will work, as the code will reference the last defined one when you invoke it. If we name them all sizepanel your code would then be
B4X:
Sub PanelPop (mlayout As String, hc As Int, wc As Int)

   pnlSelect.Initialize ( "Select")      
   pnlInput.Initialize ("")
   pnlInput.LoadLayout ( mlayout ) 
   pnlSelect.Color  = Colors.ARGB (150,0,0,0)         
   Activity.AddView (pnlSelect, 0, 0,   100%x, 100%y)   
   mh1=(pnlSelect.Height/2) - (sizepanel.Height/2) + hc
   mw1=pnlSelect.Width/2 - (sizepanel.Width/2) + wc
   mh2=sizepanel.Height
   mw2=sizepanel.Width
   pnlSelect.AddView (pnlInput, mw1, mh1, mw2, mh2)
   'Example: edittexturl.Text=HomePage
End Sub
Do not forget to Dim it in globals!

Sorry, can offer no help on the debugger.

I think your on to something! I believe that will work and do what is needed. I went to a backup of the code from last Friday and it runs fine in the debugger. Now I have to find out what in the code brakes a debugger. I have added over 1,000 lines of code from Friday. Well now I know it's in the code somewhere related to the API calls. I will try the other code and report back.

Thank You,

Margret
 

margret

Well-Known Member
Licensed User
Longtime User
Panel Issue

I have just had a thought, is the panel you are getting the size of ONLY there to define the size of the pop-up on each layout?

If that is the case, give them the same name ON EVERY LAYOUT.

This will work, as the code will reference the last defined one when you invoke it. If we name them all sizepanel your code would then be
B4X:
Sub PanelPop (mlayout As String, hc As Int, wc As Int)

   pnlSelect.Initialize ( "Select")      
   pnlInput.Initialize ("")
   pnlInput.LoadLayout ( mlayout ) 
   pnlSelect.Color  = Colors.ARGB (150,0,0,0)         
   Activity.AddView (pnlSelect, 0, 0,   100%x, 100%y)   
   mh1=(pnlSelect.Height/2) - (sizepanel.Height/2) + hc
   mw1=pnlSelect.Width/2 - (sizepanel.Width/2) + wc
   mh2=sizepanel.Height
   mw2=sizepanel.Width
   pnlSelect.AddView (pnlInput, mw1, mh1, mw2, mh2)
   'Example: edittexturl.Text=HomePage
End Sub

This did work but I now have a new problem with this. I am using a WebView for the main activity. If a webpage with a flash object is being viewed and you pull up one of these panels, the flash object is on top of the panel. I have tried most everything I could think of and the flash object is still on top. It's like the flash object has an all ways on top setting. Any ideas how to correct this?

Thanks,

Margret
 

kickaha

Well-Known Member
Licensed User
Longtime User
So happy that it is now working.

I have not got a clue about the webview issue, you need the real experts for that one!

I suggest you start a new thread with the question so that it does not get overlooked.
 

Widget

Well-Known Member
Licensed User
Longtime User
I downloaded the TwoActivities.zip file from the link in the tutorial, but the Designer shows no views in the activity for any of the screens. In other words the designer is blank. If I compile the app, it will ask me to save the blank layout. I cancel the save and when the app runs, it runs fine, showing the button and listview. The app works ok. But why doesn't the designer show the views?

Widget
 

Widget

Well-Known Member
Licensed User
Longtime User
In the Designer you must select a layout file if there are more than one file.

Klaus,
Thanks. I finally realized that I have to select File > layout in the Designer. It just wasn't intuitive. :confused:

I think it would be more obvious if the Designer had a Layout combo box above the Views combo box. That way I can easily select the Layout and then see the Views within that layout. This would be more hierarchical and the developer would have immediate access to the layouts (scroll through them) instead of going up to the File menu.

:sign0163:

Widget
 

Ramirez

Member
Licensed User
Longtime User
Sorry to up this thread, but I'm French and I'm not sure to undestand :signOops:

If an activity call another one, the second activity is launched and the first is paused ? If the system need free memory at this time, is the first activity deleted from memory or not ?

Thanks.
 

AscySoft

Active Member
Licensed User
Longtime User
I think it would be more obvious if the Designer had a Layout combo box above the Views combo box. That way I can easily select the Layout and then see the Views within that layout. This would be more hierarchical and the developer would have immediate access to the layouts (scroll through them) instead of going up to the File menu.

+1 Subscribe to that...Designer need to be "redesign" ... no rush but please do so! Also integration into main IDE will be nice (I'm working with many projects at once, for my learning, and is hard not to mess things up)
Sorry for the offtopic.
 
Top