Android Tutorial Custom View with Designer Support

Status
Not open for further replies.
Edit: please see the updated tutorial: https://www.b4x.com/android/forum/threads/62488/#content

Starting from v2.70, the visual designer supports custom views.

Note that the WYSIWYG designer (which runs on a real device / emulator) shows a place-holder instead of the custom view.

Adding the custom views with the designer is simpler and allows the developer to build and maintain the complete UI with the visual designer and designer script.

Custom views with designer support can be implemented as a class or inside a library.

Using custom views

1. Add the class or library to your project.
2. In the designer add a CustomView:

SS-2013-05-06_20.45.18.png


3. Set the custom type property:

SS-2013-05-06_20.45.50.png


4. You can now set the view properties and also treat it like any other view in the designer script.

5. Add the required declarations and events:

SS-2013-05-06_20.46.59.png


Note that the view's runtime appearance depends on the implementation. It might ignore some of the properties.

Implementing a custom view with designer support

There are two ways to implement a custom view. It can be implemented as a class (which can also be compiled to a library) or it can be implemented in Java. A tutorial about Java implementation will be available in the "libraries developers forum".

The following two subs are required in order to be supported by the designer:
B4X:
Sub Initialize (TargetModule As Object, EventName As String)

Sub DesignerCreateView(Base As Panel, Lbl As Label, Props As Map)
When a layout file is loaded the Initialize method will be called followed by a call to DesignerCreateView.

Initialize sub parameters:

TargetModule - references the module that loads the layout file.
EventName - the events name property.

These two parameters allow you to later raise events like all standard views.

DesignerCreateView parameters:

Base - a panel that will be the parent for your custom view. The panel background and layout will be based on the values from the designer. Note that you are free to do whatever you need with this panel.

Lbl - the purpose of the label is to hold all the text related properties. The label will not appear (unless you explicitly add it).

Props - a Map with additional entries. Currently the only entry is an "activity" key that holds a reference to the parent Activity object.

The following example creates a button that supports double click and single click events. Note that this example is a bit simplistic.
B4X:
'Events declaration
#Event: DoubleClick
#Event: SingleClick
'Class module
Sub Class_Globals
   Private mTarget As Object
   Private mEventName As String
   Private btn As Button
   Private topPanel As Panel
   Private downTime As Long
   Private timer1 As Timer
End Sub

Public Sub Initialize (TargetModule As Object, EventName As String)
   mTarget = TargetModule
   mEventName = EventName
   timer1.Initialize("timer1", 300)
End Sub


Public Sub DesignerCreateView(Base As Panel, Lbl As Label, Props As Map)
   btn.Initialize("")
   'create a button and add it to the Base panel.
   Base.AddView(btn, 0, 0, Base.Width, Base.Height)
   btn.TextSize = Lbl.TextSize
   btn.TextColor = Lbl.TextColor
   btn.Gravity = Lbl.Gravity
   btn.Text = Lbl.Text
   btn.Typeface = Lbl.Typeface
   topPanel.Initialize("topPanel")
   'Add a transparent panel over the button.
   'the panel will handle the touch event.
   Base.AddView(topPanel, 0, 0, Base.Width, Base.Height)
End Sub

Private Sub topPanel_Touch (Action As Int, X As Float, Y As Float)
   If Action = topPanel.ACTION_DOWN Then
      If downTime + timer1.Interval > DateTime.Now Then
         timer1.Enabled = False
         'raise the DoubleClick event
         CallSub(mTarget, mEventName & "_" & "DoubleClick")
      Else
         downTime = DateTime.Now
         timer1.Enabled = True
      End If
   End If
End Sub

Private Sub Timer1_Tick
   timer1.Enabled = False
   'raise the event
   CallSub(mTarget, mEventName & "_" & "SingleClick")
End Sub
 
Last edited:

andrewj

Active Member
Licensed User
Longtime User
Hi Erel,
Thanks for the quick response.

I don't quite understand #1. Are you saying that there is no way to create a custom view which is recognised as a view in my code?
Andrew
 
Last edited:

klaus

Expert
Licensed User
Longtime User
Have a look at the ClsLimitBar2 and LblLimitBar2 examples in the User's Guide.
The first example has the code of the class.
The second example uses the first one compiled into a library, with one customview added in the Designer and one in the code .
 

jnbarban

Member
Licensed User
Longtime User
hi, i trying to understand how use Custom view.
But, when i follow the Tutorial, at the 3rd step
3. Set the custom type property:
, the liste of type is empty.

i doing somthing wrong ?
 

Cableguy

Expert
Licensed User
Longtime User
Hi EREL...

Since the IDE is changing, I wonder if the designer and its custom view support will evolve too?
 

DonManfred

Expert
Licensed User
Longtime User
Don't know yet about the support for custom properties.
So it is not a no actually... Would like to see the Designer supports custom properties for Designerviews. I´ve already written a thread in the wish forum about this :)

But first we need a new B4A ide at all :D
 

Cableguy

Expert
Licensed User
Longtime User
The actual support only lacks the custom properties... since a custom view with designer support holds a props map, adding props to it and defining its type should/could provide an easy way for the designer to retrieve those fields...
 

demasi

Active Member
Licensed User
Longtime User
Hello,
I´m trying this Custom View example (double click button) but the events like touch are never fired.
What am I doing wrong?

B4X:
'Events declaration
#Event: DoubleClick
#Event: SingleClick
'Class module
Sub Class_Globals
   Private mTarget As Object
   Private mEventName As String
   Private btn As Button
   Private topPanel As Panel
   Private downTime As Long
   Private timer1 As Timer
End Sub

Public Sub Initialize (TargetModule As Object, EventName As String)
   Log("initialize")
   mTarget = TargetModule
   mEventName = EventName
   timer1.Initialize("timer1", 300)
End Sub


Public Sub DesignerCreateView(Base As Panel, Lbl As Label, Props As Map)
   btn.Initialize("")
   Log("createview")
   'create a button and add it to the Base panel.
   Base.AddView(btn, 0, 0, Base.Width, Base.Height)
   btn.TextSize = Lbl.TextSize
   btn.TextColor = Lbl.TextColor
   btn.Gravity = Lbl.Gravity
   btn.Text = Lbl.Text
   btn.Typeface = Lbl.Typeface
   topPanel.Initialize("topPanel")
   'Add a transparent panel over the button.
   'the panel will handle the touch event.
   Base.AddView(topPanel, 0, 0, Base.Width, Base.Height)
End Sub

Sub topPanel_Click
    Log("click")
End Sub


Private Sub topPanel_Touch (Action As Int, X As Float, Y As Float)
    Log("touch")
   If Action = topPanel.ACTION_DOWN Then
      If downTime + timer1.Interval > DateTime.Now Then
         timer1.Enabled = False
         'raise the DoubleClick event
        Log(mEventName & "_" & "DoubleClick")
         CallSub(mTarget, mEventName & "_" & "DoubleClick")
      Else
         downTime = DateTime.Now
         timer1.Enabled = True
      End If
   End If
End Sub

Private Sub Timer1_Tick
    Log("timer")
   timer1.Enabled = False
   'raise the event
        Log(mEventName & "_" & "SingleClick")
   CallSub(mTarget, mEventName & "_" & "SingleClick")
End Sub
 

Attachments

  • project.zip
    7.9 KB · Views: 560

Cableguy

Expert
Licensed User
Longtime User
You shouldn't reuse a "général info" thread to post your questions, start a new thread instead!
About the event, you should first test if the sub exists in the calling module!
 

LucaMs

Expert
Licensed User
Longtime User
Was the panel Base initialized with an empty string as event name?
(I should write better my questions and delete the one above :D: what is the event name of the panel Base?)

I tried to intercept its events but without success (Base_Click does not work).

[I know I might add a transparent panel]
 
Last edited:

LucaMs

Expert
Licensed User
Longtime User
I think that this statement needs an update:
Props - a Map with additional entries. Currently the only entry is an "activity" key that holds a reference to the parent Activity object.


I get a strange behavior (I will open a new thread, probably) copying the source code of a custom view to another (different project): in the original, Props contains two keys not present in the copy: TextColor and Color.
 
Status
Not open for further replies.
Top