Android Tutorial LayoutView: The alternative way to load and use your layouts

Introduction

Following the moto design-more-code-less in our encapsulated b4a development speed-wagon, I created a LayoutView class that is also the core of the DialogView in the XtraViews library.

This tutorial is available in the latest XtraViews package and as standalone APK

How to use

Lets take as an example the sample1 project in the layoutview\samples folder. The sample has 4 edge anchored dummy buttons and a button that changes the text of all buttons to a random generated one each time clicked.

upload_2014-7-22_7-14-59.png



This is how we do it without using the LayoutView class:

In order to access the buttons, we must switch to the designer and generate all declarations
B4X:
Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.

    Private Button1 As Button
    Private Button2 As Button
    Private Button3 As Button
    Private Button4 As Button
End Sub
Load our layout
B4X:
Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:

    Activity.LoadLayout("Layout1")
End Sub
Write our handler
B4X:
Sub BtnChangeButtons_Click
    Button1.Text = "#" & Rnd(100,999)
    Button2.Text = "#" & Rnd(100,999)
    Button3.Text = "#" & Rnd(100,999)
    Button4.Text = "#" & Rnd(100,999)
End Sub


Well, there is nothing wrong with that. But, switching between designer and code or trying to access a layout view without having generated the appropriate declaration can be some times very annoying.

Now, let's see how LayoutView can help.

In our sample project, we instantiate our LayoutView object once.
B4X:
Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.

    Dim Layout As LayoutView
End Sub
Load our layout using the LayoutView (Layout)
B4X:
Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:

    Layout.LoadLayout("Layout1")
End Sub
Tip: You may load the layout and set an html enabled title as well
B4X:
Layout.LoadLayoutWithTitle("Layout1", "<b><font color=cyan>HTML</font></b> <i>title!</i>")
And rewrite our handler using the Layout instance
B4X:
Sub BtnChangeButtons_Click
    Layout.Button("button1").Text = "#" & Rnd(100,999)
    Layout.Button("button2").Text = "#" & Rnd(100,999)
    Layout.Button("button3").Text = "#" & Rnd(100,999)
    Layout.Button("button4").Text = "#" & Rnd(100,999)
End Sub
Tip: You can still get an abstract Object by using the LayoutView.Get method
B4X:
Dim Button1 as Button = Layout.Get("button1")
Button1.Text = "#" & Rnd(100,999)

Note: The LayoutView class supports all known view classes (Layout.Label("label1"), Layout.SeekBar("seekbar1") and so on).

That means that we instantiate a global LayoutView once and after that we can get a reference to ANY object in our layout at ANY given time without the need to declare that object.

--
Related tutorials:

That's all for now folks! :D
 
Last edited:

Periklis Koutsogiannis

Active Member
Licensed User
Longtime User
Coming soon: Automatic translation of layout views using LayoutView and standard android resources!
 

stevel05

Expert
Licensed User
Longtime User
Looks good, one question about using CustomViews (Most of my layouts contain them now). I'd need to create a panel in the layout the correct size, then load a separate designer layout into that panel?

Something like:

B4X:
Layout.Panel("Panel1").LoadLayout("CustomView")

And then access the custom view in the normal manner.

Thanks for sharing.:)
 

Periklis Koutsogiannis

Active Member
Licensed User
Longtime User
Layout.LoadLayout takes a string as a parameter that defines the layout file. Can you please give me a more detailed use case?
 

stevel05

Expert
Licensed User
Longtime User
I was thinking about how to get the CustomView Object from the layout to enable calling methods in the CustomView.

I can see the custom view as part of the layout loaded with Layout.LoadLayout, but I can't do Layout.CustomView("CustomView1").method

Perhaps, you could add a Layout.Object("CustomView1") method that can be cast to the correct CustomView type, then it's methods can be called.
B4X:
Dim CV As CustomViewName = Layout.Object("CustomView1")
CV.method
 

Periklis Koutsogiannis

Active Member
Licensed User
Longtime User
@stevel05 I just did a silent update. The version number is the same. Get it.

CustomViews are more complex views because the actual object is contained. When you access them, you do not access the object itself but the contained type.

I used your ShowChord CustomView as a test case :)

B4X:
Dim Chord1 As ShowChord = Layout.CustomView("Chord1")
Chord1.DrawChord("C Maj",Array As String(0,3,2,0,1,0))
 
Last edited:

stevel05

Expert
Licensed User
Longtime User
Thank you, thats solved that one:)
 

Periklis Koutsogiannis

Active Member
Licensed User
Longtime User
Yeap, the view names are taken from the the layout views. This is the driving force of the class :)

Since the library uses the #additionalres directive, I dont think that it is 3.20 compatible :(

Hmm ... I am not quite sure if it is compatible with 3.20 or not. Lets try it and tell me please.
 

Periklis Koutsogiannis

Active Member
Licensed User
Longtime User
But I will add the 2 suggested functions later on :)

Since the LayoutView updates the activity, you can call:

B4X:
Activity.GetView(0) ' View index
Activity.GetViewName(0)
 
Last edited:

stevel05

Expert
Licensed User
Longtime User
Periklis said it's part of the library.

I should buy a newer version of B4A.
But in this way I would have too many people to help and this is a bad habit that I want to take off

Yes, but it's improving all the time, well worth it.
 
Top