B4A Library XmlLayoutBuilder - Load Xml layouts

Discussion in 'Additional libraries, classes and official updates' started by Erel, Oct 22, 2013.

  1. Erel

    Erel Administrator Staff Member Licensed User

    The standard way to build the UI in Basic4android is with the visual designer / designer script.

    You can also create UI elements by code.

    This library adds a third option which is to use xml files to define the layout. This is Google's standard method.

    This option is especially useful if you want to reuse resources created for an Android Java project.

    All three options can be combined together.

    This library provides several resources related methods. You can read more about Android resources here: http://developer.android.com/guide/topics/ui/declaring-layout.html

    Before we start you should remember that the compiler "cleans" the objects folder during compilation. The compiler will delete the extra resource files if they are not read-only.

    The simplest solution is to add the following attribute to force all the res files to be read-only:
    Code:
    #CustomBuildAction: 1, c:\windows\system32\attrib.exe, +r res\*.* /s
    You might need to correct the path.

    The example code is:
    Code:
    Sub Activity_Create(FirstTime As Boolean)
       
    Dim x As XmlLayoutBuilder
       
    'load the layout
       x.LoadXmlLayout(Activity"layout1")
       
    'load the Animation
       anim = x.LoadAnimation("wave_scale""anim")
       
    'get a view based on the id
       button1 = x.GetView("fade_animation")
       
    'get a drawable object
       Activity.Background = x.GetDrawable("smlnpatch160dpi")

       Panel1 = x.GetView(
    "panel1")
       Panel1.Color = 
    Colors.White
       
    Dim spinner1 As Spinner
       spinner1.Initialize(
    "")
       spinner1.AddAll(
    Array As String("1""2""3"))
       Panel1.AddView(spinner1, 
    00, Panel1.Width, Panel1.Height)
    End Sub
    Folder structure:

    [​IMG]

    Layout file:
    Code:
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width=
    "fill_parent"
      android:layout_height=
    "fill_parent"
      android:paddingLeft=
    "16dp"
      android:paddingRight=
    "16dp"
      android:orientation=
    "vertical" >


       <
    TextView
      android:layout_width=
    "match_parent" android:layout_height="wrap_content"
      android:layout_weight=
    "0" android:paddingBottom="4dip"
      android:textAppearance=
    "?android:attr/textAppearanceMedium"
      android:text=
    "@string/activity_animation_msg"/>

       <
    Button android:id="@+id/fade_animation"
      android:layout_width=
    "wrap_content" android:layout_height="wrap_content"
      android:text=
    "@string/activity_animation_fade"
         android:tag=
    "Button1"
         >
      <requestFocus />
      </
    Button>
       <
    Panel
         android:
    id="@+id/panel1"
      android:layout_width=
    "200dp" android:layout_height="80dp">
       </
    Panel>

      <
    CheckBox
      android:layout_width=
    "wrap_content"
      android:layout_height=
    "wrap_content"
         android:tag=
    "chk1" />
    </LinearLayout>
    LoadXmlLayout method loads the layout file and adds the views to the activity or panel.
    Once the layout is loaded you can use GetView to get a reference to a view based on the view's id attribute.

    If you want to handle the view's events then you need to set the "EventName" in android:tag attribute.
    You can handle events of the following views:
    EditText, Button, CheckBox, RadioButton, Label (TextView), AutoCompleteEditText (AutoCompleteTextView), ToggleButton, ImageView, SeekBar and Panel.

    Panel is treated differently as it is not a native view. Panel allows you to add other views (programmatically or with Panel.LoadLayout) to the loaded layout.

    LoadAnimation loads an Animation object defined in an xml file. It allows you to create all kinds of animations including a set of animations (not possible with the standard Animations library).
    http://developer.android.com/guide/topics/graphics/view-animation.html

    The other methods allow you to load drawables and strings from the resource files.

    Notes

    - When using the rapid debugger, you need to right click on the libraries tab and choose Refresh after you update the resources. Otherwise the device app may not be redeployed and the old resources will be used.
     

    Attached Files:

    Last edited: May 14, 2014
    hibrid0, luke2012, calsdn and 18 others like this.
  2. corwin42

    corwin42 Expert Licensed User

    This is great!

    Thank you very much!
     
  3. RayLee

    RayLee Member Licensed User

    Good! It's very useful!
     
  4. warwound

    warwound Expert Licensed User

    I have a problem using this library...

    I have a CustomListView and am trying to inflate an XML layout for each item in the list view.
    Only the very last list view item gets populated.

    The problem is the GetView method:

    Code:
    public View GetView(BA ba, String Name){
      
    return ba.activity.findViewById(GetResourceId("id", Name));
     
    }
    Each item in my list view contains 2 TextViews and an ImageView with unique ids.
    But as i have many list view items there are many Views in the Activity with the same id.

    What i really need to do is something like:

    Code:
    public View GetView(BA ba, ViewGroup Parent, String Name){
      
    return Parent.findViewById(GetResourceId("id", Name));
     
    }
    With this the Parent ViewGroup will contain only one View for each id.

    Does that make sense?

    Martin.
     
  5. warwound

    warwound Expert Licensed User

    A solution for my problem is to use the JavaObject library and call the findViewById method of the Panel into which i have loaded the XML layout:

    Code:
    Dim Panel1 As Panel
       
    Dim XmlLayoutBuilder1 As XmlLayoutBuilder
     
       Panel1.Initialize(
    "")
       XmlLayoutBuilder1.LoadXmlLayout(Panel1, 
    "my_layout")
     
       
    '   elsewhere in my code Panel1 is added to the Activity's layout
     
       
    Dim JavaObject1 As JavaObject
       
    Dim JavaPanel As JavaObject=Panel1
       
    Dim ResourceId As Int
     
       ResourceId=XmlLayoutBuilder1.GetResourceId(
    "id""title")
       JavaObject1=JavaPanel.RunMethod(
    "findViewById"Array As Object(ResourceId))
       JavaObject1.RunMethod(
    "setText"Array As Object("my title text"))
    So i have multiple instances of a Panel into which i have loaded the same XML layout.
    If i have 15 such Panels then the Activity contains 15 TextViews with the same "title" resource id.

    Calling the XmlLayoutBuilder GetView("title") method returns the first View found in the Activity with the resource id.

    Calling the Panel findViewById method returns the first View found in the Panel with the resource id, there's only one View in the Panel with the resource id.

    There's only one View in the Panel with this resource id but there's multiple Views in the Activity with this resource id.

    Martin.
     
    Last edited: Mar 13, 2014
  6. lonleystar

    lonleystar Well-Known Member Licensed User

    Great job,

    it´s a solution when i build some layout whith eclipse.

    Thank you Erel.
     
  7. tipallandgo

    tipallandgo Member Licensed User

    Hi, I always get a NullPointerException whenever I try to load an animation. My code is:

    Code:
    Dim xmlb As XmlLayoutBuilder
        
    Dim a As Animation
        a = xmlb.LoadAnimation(
    "wave_scale""Anim")
        a.Start(c.CardPanel)
    I put the wave_scale.xml from the example to the anim folder of my project.
     
  8. Erel

    Erel Administrator Staff Member Licensed User

    Can you post the full error message from the logs?
     
    shah2014 likes this.
  9. tipallandgo

    tipallandgo Member Licensed User

    The app is paused at
    Code:
    a = xmlb.LoadAnimation("wave_scale""Anim")
    logs:
    Code:
    java.lang.NullPointerException
        at anywheresoftware.b4a.object.XmlLayoutBuilder.LoadAnimation(
    XmlLayoutBuilder.java:81)
        at com.tip.aris_mobile.gradescreen._showinfoscreen(gradescreen.java:
    1275)
        at com.tip.aris_mobile.main._ab_itemclicked(main.java:
    548)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:
    511)
        at anywheresoftware.b4a.BA.raiseEvent2(BA.java:
    173)
        at anywheresoftware.b4a.BA.raiseEvent2(BA.java:
    161)
        at anywheresoftware.b4a.BA.raiseEvent(BA.java:
    157)
        at de.amberhome.SimpleActionBar.ActionBar$Action.select(ActionBar.java:
    1683)
        at de.amberhome.SimpleActionBar.ActionBar$
    2.onClick(ActionBar.java:262)
        at android.view.View.performClick(
    View.java:4222)
        at android.view.View$PerformClick.run(
    View.java:17273)
        at android.os.Handler.handleCallback(Handler.java:
    615)
        at android.os.Handler.dispatchMessage(Handler.java:
    92)
        at android.os.Looper.loop(Looper.java:
    137)
        at android.app.ActivityThread.main(ActivityThread.java:
    4895)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:
    511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:
    994)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:
    761)
        at dalvik.system.NativeStart.main(Native Method)
    EDIT: I just want to add more info. I'm using AHActionBar. The code I posted above is in a sub from a class that is called when the used click an action item from the actionbar.
     
  10. Erel

    Erel Administrator Staff Member Licensed User

    It is a bug in the library (which happens when you call LoadAnimation without first calling LoadXmlLayout). I will upload a new version that will fix it.
     
  11. Erel

    Erel Administrator Staff Member Licensed User

    XmlLayoutBuilder v1.00 uploaded to the first post. It should fix this issue.
     
  12. tipallandgo

    tipallandgo Member Licensed User

    Thank you! I'll try it right away.
     
  13. Eme Fibonacci

    Eme Fibonacci Well-Known Member Licensed User

    hi,

    I'm not able to catch the event:
    Sub check1_CheckedChange(Checked As Boolean)

    In XMLLayout file I added an id:
    android: id = "@ + id / check1" but
    Sub check1_CheckedChange(Checked As Boolean)

    does not work. Can help?
    Thank you.
     
  14. Erel

    Erel Administrator Staff Member Licensed User

    See how to set the event name in the first post.
     
  15. shashkiranr

    shashkiranr Active Member Licensed User

    Hi Erel,

    I have the below Custom XML (For checkbox). I need to load it and set it to the checkbox in my activity. this is a selector. i have the drawable with me.how to go about calling it in my activity

    Code:
    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android=
    "http://schemas.android.com/apk/res/android">
    <item android:state_checked=
    "true"
        android:drawable=
    "@drawable/cbchk_blue"
        android:state_focused=
    "false">
    </item>
    <item android:state_checked=
    "true"
        android:drawable=
    "@drawable/cbchk_blue"
        android:state_focused=
    "true">
    </item>
    <item android:state_checked=
    "false"
        android:drawable=
    "@drawable/cbunchk_blue"
        android:state_focused=
    "false">
    </item>
    <item android:state_checked=
    "false"
        android:drawable=
    "@drawable/cbunchk_blue"
        android:state_focused=
    "true">
    </item>
    Regards,
    SK
     
  16. Erel

    Erel Administrator Staff Member Licensed User

    You need to give it an id and then call XmlLayoutBuilder.GetDrawable and set the drawable as the checkbox background.
     
  17. salvadoro

    salvadoro Member Licensed User

    Hi Erel, im using the next xml.

    Code:
    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android=
    "http://schemas.android.com/apk/res/android"
        android:layout_width=
    "match_parent"
        android:layout_height=
    "match_parent">

        <io.vov.vitamio.widget.VideoView
            android:
    id="@+id/SurfaceView"
            android:layout_width=
    "match_parent"
            android:layout_height=
    "match_parent"
            android:layout_alignParentTop=
    "true"
            android:layout_alignParentBottom=
    "true"
            android:layout_alignParentLeft=
    "true"
            android:layout_alignParentRight=
    "true"
            android:tag=
    "VideoView1">
            </io.vov.vitamio.widget.VideoView>
        
    </RelativeLayout>
    How can i handle events for this.

    Regards,

    Salvador.
     
  18. Erel

    Erel Administrator Staff Member Licensed User

    You will not be able to handle events of a native view without adding them with JavaObject. It doesn't matter how you add the views.
     
  19. Johan Schoeman

    Johan Schoeman Expert Licensed User

    If for eg a button was created with a XML layout file, being it a RelativeLayout, AbsoluteLayout, LinearLayout, or nested layouts, can the position and size (left, top, width, height) of the button be changed from within B4A code?
     
  20. Erel

    Erel Administrator Staff Member Licensed User

    No (at least not it is not straightforward).

    When you use these layouts (except of AbsoluteLayout which doesn't really make sense to use) then you cannot simply set the views positions.
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice