Android Tutorial Example of an app with a phone and tablet layouts

This example demonstrates how you can create an app that looks and behaves differently depending whether it runs on a phone or a tablet.

The app layout is simple.
The main screen includes three buttons. Each button opens a second screen.

On the tablet the second screen is actually loaded to a panel at the right side. On the phone a second activity opens.

As you can see in this example, each screen is implemented as a class. This allows us to write the code once and use it in both scenarios.

The new UI Cloud is very helpful when designing the main layout:

SS-2012-11-05_14.52.43.png


As you can see in the above image the secondary panel is only visible on tablets.

The code itself is made of two activities: the main activity and the second activity that is only used on phones.

Each screen class must include three methods: AddToActivity, AddToPanel and Hide. These methods are called with CallSub.

The last module is a code module named ScreensManager. This module is responsible for the creation of the class objects. Note that if you add or remove screens then you should update this code.

The screen classes should be initialized with the parent activity context. Therefore the main activity cannot initialize the classes for the secondary activity.
Code modules (unlike activities and services) do not have a context of their own. Instead code modules use the same context as the calling module, which in our case will be the main activity (tablets) or secondary activity (phones).

Tablet:
SS-2012-11-05_15.02.49.png


Phone:
SS-2012-11-05_15.03.28.png
 

Attachments

  • PhoneTabletLayout.zip
    13.1 KB · Views: 3,649

barx

Well-Known Member
Licensed User
Longtime User
I can't help but feel I have created the cause for this example / solution and so I give a huge thanks for it. It looks the perfect solution for my problem and a real alternative to 'Fragments'. I haven't played with creating classes yet, so would have never come up with this myself. So, thanks a lot Erel. Your an absolute STAR!

I'm sure I'll get the hang of it after a little studying.

:sign0188:
 

Stulish

Active Member
Licensed User
Longtime User
I have just quickly used the UI cloud, and it seems to work really well. very useful

Thanks Erel:sign0098:
 

Harris

Expert
Licensed User
Longtime User
I see the example is using a 800x480 variant as well.
Is this what we use to support tablets or will the standard variant support both - using this example?

Thanks
 

Jost aus Soest

Active Member
Licensed User
Longtime User
Question / Idea

Nice shoot, thnx!

But what I do not like is the double programming caused by the phone only Activity...

Wouldn't it be a nice alternative (for the phone) to just slide away (by choosing one of the screen-buttons) the left panel and get so enough room for the right panel?

What do you think?
What are the (dis)advantages of both solutions?
 

barx

Well-Known Member
Licensed User
Longtime User
Am I right in thinking that when implementing this, any variables that would normally have gone in the Process_Globals, now needs to be in a code module?

Either the same as ScreenManager or another.
 

barx

Well-Known Member
Licensed User
Longtime User
Where do I put what would usually be in Activity_Create?

Add it to AddToActivity / AddToPanel?
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Two new features in Basic4android v2.30 will make the designer code much simpler:
- If ... Then condition blocks
- ActivitySize keyword which returns the approximate activity size measured in inches.

With these features the whole layout can be made of a single variant (instead of four) and the following script:

B4X:
'All variants script
AutoScaleAll 
pnlMain.SetTopAndBottom(0, 100%y)
If ActivitySize > 6 Then 'tablets
   pnlMain.SetLeftAndRight(0, 40%x)
   pnlSecondScreen.Visible = true
   pnlSecondScreen.SetLeftAndRight(pnlMain.Right, 100%x)
   pnlSecondScreen.SetTopAndBottom(0, 100%y)
Else
   pnlMain.SetLeftAndRight(0, 100%x)
End If
Button1.SetLeftAndRight(10dip, pnlMain.Right - 10dip)
Button2.SetLeftAndRight(10dip, pnlMain.Right - 10dip)
Button3.SetLeftAndRight(10dip, pnlMain.Right - 10dip)

A single variant is much more easier to maintain...
 

moster67

Expert
Licensed User
Longtime User
Sounds great Erel. Thanks!

PS: will it be possible to use the "else if" block too? If not, you might as well consider adding it from the beginning since this request might pop up later :)
 

barx

Well-Known Member
Licensed User
Longtime User
looking good!
 

barx

Well-Known Member
Licensed User
Longtime User
I'm using this method, although modified slightly and have a little issue, wondering if you have any thoughts.

I load the app, choose an item and the activity (Class) loads as desired.
I hit back and am returned to the home main menu activity, then upon selecting another item I get a brief flash of the last loaded class before the currently selected one is displayed

I've tried adding a activity.RemoveAllViews and activity.Invalidate at various point but I cannot seem to rid the bug.

p.s. I would prefer not to upload to public my project but can send via email if you wish, thanks
 

barx

Well-Known Member
Licensed User
Longtime User
Yes I have, and also the first thing in Activity_Create to try on do it before new activity shows. Also popped a DoEvents in for good measure so Invalidate would hopefully draw the blank activity.

My device is quite slow ( HTC Desire Z, 800MHz cpu) I'm not sure if it would be visible on a faster device but the wife if out with her sgs3 to try.

I'm off out myself shortly so I will send the .zip to support @ basic4ppc . com.

Just noticed the beta release so understand you are busy at moment so if you don't get time to look the no worries.

Also, noticed that in debug processing wouldn't stop at a breakpoint in activity_Pause so thought it was being skipped somehow, but I added some logging and it shows ok.
 

barx

Well-Known Member
Licensed User
Longtime User
issue fixed.

Needed to set screenIndex = 0 like below.

B4X:
Sub Activity_Pause (UserClosed As Boolean)
   If UserClosed Then
      CallSub(currentScreen, "UserClosed")
      Log("Closed by user")
      screenIndex = 0 '<-------
   Else
      CallSub(currentScreen, "Hide")
      Log("Closed")
   End If
End Sub
 

AHilton

Active Member
Licensed User
Longtime User
Erel,

In your example, clsScreen3 button, how would you get back to the main screen (the one with the buttons) with no screen showing. Just the main layout with the 3 buttons and the secondary panel or activity not showing? In other words, back to the 'main screen' programmatically from within one of the screen classes.


Never mind. Figured it out.
 
Last edited:
Top