Android Tutorial How I wrapped a HTML5, JavaScript & Css based Library...

Discussion in 'Tutorials & Examples' started by Mashiane, Feb 2, 2017.

  1. Mashiane

    Mashiane Expert Licensed User

    Hi there..

    Eye Candy

    To be able to do this, you need a good library that you want to wrap. A library like this will run inside a webview as its purely javascript, so some knowledge of HTML5 at most and some css will be recommended. I'm still learning both through trial and error.

    Secondly, I wanted to trap the events that happen within my components, so I used webview extras for that.

    Thirdly, I wanted to have the library include internaly the javascript and css files that I'm using. Please note the respective licenses for that. I decided on some community based libraries.

    Steps

    1. Create a project in b4a and insert the normal library attributes... Here is an example. This should be in the Main activity

    Code:
    #Region  Project Attributes
        
    #LibraryName: AMTileView108
        
    'SupportedOrientations possible values: unspecified, landscape or portrait.
        #SupportedOrientations: unspecified
        
    #CanInstallToExternalStorage: false
        
    #LibraryAuthor: Anele Mbanga - anele@mbangas.com
        
    #LibraryVersion: 1.08
    #End Region
    2. My library is based on the premise that it will run inside a webview, so I needed to create a page where all components will sit. This I created a page class to be a holder using HTML5 methodology. This page will parent the other components, will fire javascript code using WebViewExtras etc and will get and set components attributes during run time.

    As my page will fire events, I created some events and also some design properties (this I will test later on). This I did by adding a CustomView class and updating the events...

    Code:
    #Event: TileClicked (value As String)
    #Event: TabClicked (value As String)
    #Event: MenuClicked (value As String, childIndex as string)
    #Event: GroupButtonClick (value As String)
    #Event: RadialSliderChange (element as String, Value as string)
    #Event: RangeSliderChange (element as String, Value as string)
    #Event: RatingChange (element as string, value as string)
    #Event: Loaded ()
    #Event: RangeSliderRead(value1 as string, value2 as string)
    3. I then defined some global variables I will use and also the interface with the webview extras library on this page class...

    Code:
    Sub Class_Globals
        
    Public ID As String
        
    Private jsFiles As List
        
    Private cssFiles As List
        
    Public PageName As String
        
    Public Title As String
        
    Public Description As String
        
    Public Author As String
        
    Public Minify As Boolean
        
    Private EventName As String 'ignore
        Private CallBack As Object 'ignore
        Private mBase As Panel
        
    Private webTile As WebView
        
    Dim we As WebViewExtras
        
    Dim client As DefaultWebChromeClient
        
    Dim jsi As DefaultJavascriptInterface
        
    Type RenderModeEnum(windows As String, auto As String, ios7 As String, android As String, flat As String)
        
    Public EnumRenderMode As RenderModeEnum
        
    Public FontSize As String
        
    Public FontFamily As String
        
    Public BackgroundImage As String
        
    Public BackgroundColor As String
        
    Public jfl As JarFileLoader
        
    Public ShowProgress As Boolean
        
    Public ProgressMessage As String
        
    Public DebugMode As Boolean
        
    Private pageDiv As HTMLElement
        
    Public HasScrollPanel As Boolean
        
    Private sv As HTMLElement
        
    Type OrientationEnum(vertical As String, horizontal As String)
        
    Public EnumOrientation As OrientationEnum
        
    Type PrecisionEnum(Full As String, Half As String, Exact As String)
        
    Public EnumPrecision As PrecisionEnum
        
    Type ShapeEnum(star As Stringcircle As String, diamond As String, heart As String, pentagon As String, square As String, triangle As String)
        
    Public EnumShape As ShapeEnum
        
    Type PagerPositionEnum(top As String, bottom As String, left As String, right As String)
        
    Public EnumPagerPosition As PagerPositionEnum
        
    Public RenderMode As String
        
    Public ShowScrollBars As Boolean
        
    Type itemStyleEnum(bothblock As Stringimage As String)
        
    Public EnumItemStyle As itemStyleEnum
        
    Type IconsEnum(iconadd As String, iconback As String, iconbookmark As String, iconclose As String, iconcompose As String, iconcopy As String, iconcut As String, _
        icondelete 
    As String, icondone As String, iconedit As String, iconmail As String, iconnext As String, iconrefresh As String, iconoverflow As String, _
        iconpaste 
    As String, iconreply As String, iconsave As String, iconsearch As String, iconsettings As String, iconshare As String)
        
    Public EnumIcons As IconsEnum
    End Sub
    From above, the most important crucial things are the webview (we will render our components in it), the JarFileLoader (this extracts js and css files from the compiled .jar file), the WebViewExtras, WebChromeClient and JSInterface), without these, this library would not work at all.

    The output of the final library for me has been the Eye Candy above, all purely javascript and some css.
     

    Attached Files:

    Last edited: Feb 3, 2017
  2. Mashiane

    Mashiane Expert Licensed User

    4. I wanted my library to be able to be added to an activity and also to a panel, so I defined two methods to achieve this, we are still in the same AMPage class.

    Code:
    'add control to activity   
    Public Sub AddToActivity(Parent As Activity, Left As Int, Top As Int, Width As Int, Height As Int)
        Parent.AddView(mBase, Left, Top, Width, Height)
    End Sub

    'add control to panel
    Public Sub AddToPanel(Parent As Panel, Left As Int, Top As Int, Width As Int, Height As Int)
        Parent.AddView(mBase, Left, Top, Width, Height)
    End Sub
       
    'Initializes the object. You can add parameters to this method if needed.
    Public Sub Initialize(vCallback As Object, vEventName As String)
        EventName = vEventName
        CallBack = vCallback
        Init
    End Sub
     
  3. Mashiane

    Mashiane Expert Licensed User

    5. The Init method from the above Initialize methods, does the basic setups of the environment. This will extracts the necessary needed files and also I add the methods that will be executed via javascript but called within my b4a app using webviewextras.


    Code:
    Private Sub Init
        EnumIcons.Initialize
        EnumIcons.iconadd = 
    "Add"
        EnumIcons.iconback = 
    "Back"
        EnumIcons.iconbookmark = 
    "Bookmark"
        EnumIcons.iconclose = 
    "Close"
        EnumIcons.iconcompose = 
    "Compose"
        EnumIcons.iconcopy = 
    "Copy"
        EnumIcons.iconcut = 
    "Cut"
        EnumIcons.icondelete = 
    "Delete"
        EnumIcons.icondone = 
    "Done"
        EnumIcons.iconedit = 
    "Edit"
        EnumIcons.iconmail = 
    "Mail"
        EnumIcons.iconnext = 
    "Next"
        EnumIcons.iconrefresh = 
    "Refresh"
        EnumIcons.iconoverflow = 
    "Overflow"
        EnumIcons.iconpaste = 
    "Paste"
        EnumIcons.iconreply = 
    "Reply"
        EnumIcons.iconsave = 
    "Save"
        EnumIcons.iconsearch = 
    "Search"
        EnumIcons.iconsettings = 
    "Settings"
        EnumIcons.iconshare = 
    "Share"
     
        EnumItemStyle.Initialize
        EnumItemStyle.bothblock = 
    "bothblock"
        EnumItemStyle.image = 
    "image"
        ShowScrollBars = 
    True
        RenderMode = 
    "ios7"
        EnumPagerPosition.Initialize
        EnumPagerPosition.bottom = 
    "bottom"
        EnumPagerPosition.left = 
    "left"
        EnumPagerPosition.right = 
    "right"
        EnumPagerPosition.top = 
    "top"
        EnumShape.Initialize
        EnumShape.star = 
    "star"
        EnumShape.circle = 
    "circle"
        EnumShape.diamond = 
    "diamond"
        EnumShape.heart = 
    "heart"
        EnumShape.pentagon = 
    "pentagon"
        EnumShape.square = 
    "square"
        EnumShape.triangle = 
    "triangle"
        EnumPrecision.Initialize
        EnumPrecision.Exact = 
    "exact"
        EnumPrecision.Full = 
    "full"
        EnumPrecision.Half = 
    "half"
        EnumOrientation.Initialize
        EnumOrientation.vertical = 
    "vertical"
        EnumOrientation.horizontal = 
    "horizontal"
        pageDiv.Initialize(
    "page""div")
        pageDiv.AddAttribute(
    "data-role""appview")
        pageDiv.AddClass(
    ID & "bg")
        
    'init the scrollview
        sv.Initialize("scroller","div")
        sv.AddAttribute(
    "data-role","ejmscrollpanel")
        sv.AddAttribute(
    "data-ej-target""page")
        webTile.Initialize(
    "webTile")
        mBase.Initialize(
    "mBase")
        webTile.JavaScriptEnabled = 
    True
        webTile.ZoomEnabled = 
    False
        we.Initialize(webTile)
        jsi.Initialize
        we.addJavascriptInterface(jsi, 
    "B4A")
        we.JavaScriptEnabled = 
    True
        client.Initialize(
    "wcc")
        we.SetWebChromeClient(client)
        mBase.AddView(webTile,
    0dip,0dip,100%x,100%y)
        ShowProgress = 
    True
        ProgressMessage = 
    "Working on it, please wait..."
        
    'extract the library contents
        jfl.Initialize(False)
        
    'jfl.AssetFromJar("bootstrap.min.css")
        jfl.AssetFromJar("ej.mobile.all.min.css")
        
    'jfl.assetfromjar("angular.min.js")
        'jfl.AssetFromJar("bootstrap.min.js")
        'jfl.AssetFromJar("ej.globalize.min.js")
        jfl.AssetFromJar("ej.mobile.all.min.js")
        jfl.AssetFromJar(
    "ej.unobtrusive.min.js")
        
    'jfl.AssetFromJar("ej.widget.angular.min.js")
        'jfl.assetfromjar("ej.widget.ko.min.js")
        'jfl.AssetFromJar("excanvas.min.js")
        jfl.AssetFromJar("jquery.easing.1.3.min.js")
        jfl.AssetFromJar(
    "jquery-3.1.1.min.js")
        jfl.AssetFromJar(
    "jsrender.min.js")
        
    'jfl.AssetFromJar("knockout.min.js")
     
        EnumRenderMode.Initialize
        EnumRenderMode.windows = 
    "windows"
        EnumRenderMode.auto = 
    "auto"
        EnumRenderMode.android = 
    "android"
        EnumRenderMode.flat = 
    "flat"
        EnumRenderMode.ios7 = 
    "ios7"
        Title = 
    "page"
        cssFiles.Initialize
        jsFiles.Initialize
        Description = 
    ""
        Author = 
    ""
        Minify = 
    False
        LoadSyncfusionFramework
        AddJSCode(
    "function menuclicked(e) {B4A.CallSub('menuclicked', false, e.index, e.childIndex);}")
        AddJSCode(
    "function groupbuttonclick(args) {B4A.CallSub('groupbuttonclick', false, args.text);}")
        AddJSCode(
    "function menucontrolclicked(args) {B4A.CallSub('menucontrolclicked', false, args.text);}")
        AddJSCode(
    "function tabclick(args) {B4A.CallSub('tabclick', false, args.id);}")
        AddJSCode(
    "function tileclicked(args) { var id = this.element[0].id; B4A.CallSub('tileclicked', false, id);}")
        
    'debug the page
        'Dim WVJO As JavaObject = webTile
        'WVJO.RunMethod("setWebContentsDebuggingEnabled",Array(True))
        ' open browser in chrome://inspect/#devices
        ' see here https://developers.google.com/web/tools/chrome-devtools/remote-debugging/?hl=en
        FontSize = ""
        BackgroundColor = 
    ""
        HasScrollPanel = 
    True
    End Sub
    As you might have noted, my library is based on Synfusion controls, thus my page structure meets that definition. The AddJSCode method will add those javascript pieces to the page definition I'm trying to create here.

    The purpose of this is to have the skeleton HTML content of the page to put the components in. I will discuss the jfl methods later on.
     
    Last edited: Feb 2, 2017
  4. Mashiane

    Mashiane Expert Licensed User

    6. Then I linked the javascript code to the code that should be called linked to the b4a events..

    This line above, speaks to this code, thus, when the menucontrolclicked javascript is called when a user executes a command, then b4a MenuControlClicked event will be fired. If you did see the RadialMenu, each time you clicked a menu item, the Activity.Title, changed, this is how this was achieved, by linking javascript to b4a using WebViewExtras. Powerful Library that is.

    AddJSCode("function menucontrolclicked(args) {B4A.CallSub('menucontrolclicked', false, args.text);}")

    Code:
    'radial slider change
    private Sub menucontrolclicked(value As String)
        
    If SubExists(CallBack, EventName & "_MenuControlClicked"Then
            CallSubDelayed2(CallBack,EventName & 
    "_MenuControlClicked", value)
        
    End If
    End Sub


    'radial slider change
    private Sub tabclick(element As String, value As String)
        
    If SubExists(CallBack, EventName & "_TabClicked"Then
            CallSubDelayed3(CallBack,EventName & 
    "_TabClicked", element, value)
        
    End If
    End Sub

    'radial slider change
    private Sub rangesliderchange(element As String, value As String)
        
    If SubExists(CallBack, EventName & "_RangeSliderChange"Then
            CallSubDelayed3(CallBack,EventName & 
    "_RangeSliderChange", element, value)
        
    End If
    End Sub

    'radial slider change
    private Sub radialsliderchange(element As String, value As String)
        
    If SubExists(CallBack, EventName & "_RadialSliderChange"Then
            CallSubDelayed3(CallBack,EventName & 
    "_RadialSliderChange", element, value)
        
    End If
    End Sub

    'rating changed
    private Sub ratingchange(element As String, value As String)
        
    If SubExists(CallBack, EventName & "_RatingChange"Then
            CallSubDelayed3(CallBack,EventName & 
    "_RatingChange", element, value)
        
    End If
    End Sub

    'run when a tile is clicked
    private Sub tileclicked(value As String)
        
    If SubExists(CallBack, EventName & "_TileClicked"Then
            CallSubDelayed2(CallBack,EventName & 
    "_TileClicked", value)
        
    End If
    End Sub

    'run when a tile is clicked
    private Sub groupbuttonclick(value As String)
        
    If SubExists(CallBack, EventName & "_GroupButtonClick"Then
            CallSubDelayed2(CallBack,EventName & 
    "_GroupButtonClick", value)
        
    End If
    End Sub

    'run when a tile is clicked
    private Sub menuclicked(value As String, childIndex As String)
        
    If SubExists(CallBack, EventName & "_MenuClicked"Then
            CallSubDelayed3(CallBack,EventName & 
    "_MenuClicked", value, childIndex)
        
    End If
    End Sub
     
  5. Mashiane

    Mashiane Expert Licensed User

    7. The AMPage HTML

    Code:
    'return the html content in html
    Public Sub HTML() As String
        
    If FontSize.Length > 0 Or FontFamily.Length > 0 Then
            
    Dim css As CssElement
            css.Initialize(
    "body")
            
    If FontSize.Length > 0 Then css.AddAttribute("font-size", FontSize & "px")
            
    If FontFamily.Length > 0 Then  css.AddAttribute("font-family", FontFamily)
            AddStyle(css.HTML)
        
    End If
        
    Dim sb As StringBuilder
        sb.Initialize
        
    Dim sm As String = $"<!DOCTYPE html>
        <html lang="en">
        <head>
        <meta name="msapplication-tap-highlight" content="no" />
        <meta id="viewport" name="viewport" content="width=device-width, initial-scale=1.0,maximum-scale=1.0, user-scalable=no" />
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
        <meta name="format-detection" content="telephone=no">
        <meta name="apple-mobile-web-app-capable" content="yes" />
        <meta name="description" content="<<description>>" />
        <meta name="author" content="<<author>>" />
        <title><<title>></title>"$

        sb.Append(sm)
        
    'add the css files
        For Each strCSS As String In cssFiles
            sb.Append(AddLink(strCSS))
        
    Next
        
    'add javascript files
        For Each strJS As String In jsFiles
            sb.Append(AddJS(strJS))
        
    Next
        sb.Append(
    CRLF)
        sb.append(
    "</head>").Append(CRLF)
        sb.Append(
    "<body>").Append(CRLF)
        sb.Append(pageDiv.GetStyles)
        sb.Append(pageDiv.HTML)
        
    If HasScrollPanel = True Then
            sv.AddAttribute(
    "data-ej-rendermode", RenderMode)
            
    If ShowScrollBars = False Then sv.AddAttribute("data-ej-showscrollbars"False)
            sb.Append(sv.HTML)
        
    End If
        sb.Append(pageDiv.GetJavaScript)
        sb.Append(
    "</body>").Append(CRLF)
        sb.Append(
    "</html>").Append(CRLF)
        
    Dim strOut As String = sb.ToString
        strOut = strOut.Replace(
    "<<description>>", Description)
        strOut = strOut.Replace(
    "<<author>>", Author)
        strOut = strOut.Replace(
    "<<title>>", Title)
        strOut = strOut.trim
        
    If Minify = True Then
            
    Return strOut.Replace(CRLF,"")
        
    Else
            
    Return strOut
        
    End If
    End Sub
    This code here will build the page HTML structure including everything we need. You also need to just achieve that point, by ensuring that your page HTML code is correct to be able to be discplayed in the webview.
     
  6. Mashiane

    Mashiane Expert Licensed User

    8. The next step was then to build each of the elements that I want to be displayed in the page depending on my needs.

    Below is the code for the AMButtonGroup component of the AMTileView library.

    Code:
    Sub Class_Globals
        
    Public ID As String
        
    Private page As AMPage
        
    Private gb As HTMLElement
        
    Private gbh As HTMLElement
        
    Public RenderMode As String
        
    Public MultipleSelect As Boolean
    End Sub

    'Initializes the object. You can add parameters to this method if needed.
    Public Sub Initialize(pg As AMPage, sID As String)
        MultipleSelect = 
    False
        
    ID = sID
        
    page = pg
        gbh.Initialize(sID & 
    "sample","div")
        gbh.AddClass(sID & 
    "sample")

        
    Dim css As CssElement
        css.Initialize(
    "." & sID & "sample")
        css.AddAttribute(
    "padding-top""20px")
        css.AddAttribute(
    "text-align""center")
        
    'center the group button
        css.AddAttribute("display""table")
        css.AddAttribute(
    "margin""0 auto")
        
    page.AddStyle(css.HTML)
      
        gb.Initialize(sID,
    "div")
        gb.AddAttribute(
    "data-role""ejmgroupbutton")
        gb.addattribute(
    "data-ej-selecteditemindex","0")
        gb.AddAttribute(
    "data-ej-touchend""groupbuttonclick")
        RenderMode = pg.EnumRenderMode.ios7
    End Sub

    'add a style to the element
    Sub AddStyle(value As String)
        
    page.AddStyle(value)
    End Sub

    'add a class to the element
    Sub AddClass(value As String)
        gb.AddClass(value)
    End Sub

    'set the selected index
    Sub SetSelectedIndex(idx As Int)
        gb.addattribute(
    "data-ej-selecteditemindex",idx)
    End Sub

    'add a button
    Sub AddButton(bid As String, bCaption As String, imageURL As String, imageInternal As Boolean)
        
    If imageURL.Length > 0 Then
            
    If imageInternal = True Then
                imageURL = modHTML.WebViewAssetFile(imageURL)
            
    End If
        
    End If
        
    'build the image class for the button
        If imageURL.Length > 0 Then
            
    Dim imgclass As CssElement
            imgclass.Initialize(
    "." & bid)
            imgclass.AddAttribute(
    "background""url(" & imageURL & ") no-repeat")
            imgclass.AddAttribute(
    "background-position""2px 50%")
            imgclass.AddAttribute(
    "background-repeat""no-repeat")
            imgclass.AddAttribute(
    "background-size""20px 20px")
            imgclass.AddAttribute(
    "position""relative")
            imgclass.AddAttribute(
    "text-indent""20px")
            
    page.AddStyle(imgclass.HTML)
        
    End If
        
    Dim lbl As HTMLElement
        
    Dim inp As HTMLElement
        
    'define the label
        lbl.Initialize("""label")
        
    If imageURL.Length > 0 Then lbl.AddAttribute("data-ej-imageclass", bid)
        
    'define the type
        inp.Initialize("""input")
        
    If MultipleSelect = True Then
            inp.AddAttribute(
    "type","checkbox")
        
    Else
            inp.AddAttribute(
    "type","radio")
        
    End If
        inp.AddAttribute(
    "name"ID & "options")
        inp.AddContent(bCaption)
        lbl.AddContent(inp.HTML)
        
    'add the button to the group button
        gb.AddContent(lbl.HTML)
      
        
    'add css for button
        Dim cssb As CssElement
        cssb.Initialize(
    "#" & bid)
        cssb.AddAttribute(
    "padding-top","20px")
        
    page.addstyle(cssb.HTML)
    End Sub

    'return the html
    Sub HTML As String
        
    If RenderMode.Length > 0 Then gb.AddAttribute("data-ej-rendermode", RenderMode)
        gbh.AddContent(gb.html)
        
    Return gbh.html
    End Sub


    'add the group button to the page
    Public Sub AddToPage
        
    page.AddContent(HTML)
    End Sub
    Based on my example AMGroup component... my execution code looked like this..

    Code:
    Sub Activity_Create(FirstTime As Boolean)
        
    'Do not forget to load the layout file created with the visual designer. For example:
        'Activity.LoadLayout("Layout1")
        Activity.Title = "AMGroupButton"
        
    'initialize a tile view
        pg.Initialize(Me,"pg")
        pg.AddToActivity(
    Activity,0dip,0dip,100%x,100%y)
        gb.Initialize(pg,
    "gb")
        gb.AddButton(
    "all""Apple""ios.png"True)
        gb.AddButton(
    "read""Android","android.png",True)
        gb.AddButton(
    "unread""Windows""windows.png"True)
        gb.AddToPage
        pg.Render
    End Sub
    And from there, the following HTML component was produced...

    Code:
    <div id="gbsample" class="gbsample">
    <div 
    id="gb" data-role="ejmgroupbutton" data-ej-selecteditemindex="0" data-ej-touchend="groupbuttonclick" data-ej-rendermode="ios7">
    <
    label data-ej-imageclass="all">
    <input 
    type="radio" name="gboptions">
    Apple
    </input>
    </
    label>
    <
    label data-ej-imageclass="read">
    <input 
    type="radio" name="gboptions">
    Android
    </input>
    </
    label>
    <
    label data-ej-imageclass="unread">
    <input 
    type="radio" name="gboptions">
    Windows
    </input>
    </
    label>
    </div>
    <div 
    id="gb" data-role="ejmgroupbutton" data-ej-selecteditemindex="0" data-ej-touchend="groupbuttonclick" data-ej-rendermode="ios7">
    <
    label data-ej-imageclass="all">
    <input 
    type="radio" name="gboptions">
    Apple
    </input>
    </
    label>
    <
    label data-ej-imageclass="read">
    <input 
    type="radio" name="gboptions">
    Android
    </input>
    </
    label>
    <
    label data-ej-imageclass="unread">
    <input 
    type="radio" name="gboptions">
    Windows
    </input>
    </
    label>
    </div>
    </div>
     
  7. Mashiane

    Mashiane Expert Licensed User

    9. I finished creating my components, tested them if they are working including the events that I wanted to link to them, the setters and the getters and now it was the interesting part of distributing the library. There is a module that is here in the forum to extract files from jar files. We have tweaked this for our likes, so I discovered that I needed to do the same. To distribute my library this is what I did.

    1. My library includes a tweaked version of the JarFileLoader, when the library is initialized, the js and css files are extracted from the library and put into temporal storage.
    2. Due to permission issues, I also added RunTimePermissions

    Code:
    ProgressMessage = "Working on it, please wait..."
        
    'extract the library contents
        jfl.Initialize(False)
        
    'jfl.AssetFromJar("bootstrap.min.css")
        jfl.AssetFromJar("ej.mobile.all.min.css")
        
    'jfl.assetfromjar("angular.min.js")
        'jfl.AssetFromJar("bootstrap.min.js")
        'jfl.AssetFromJar("ej.globalize.min.js")
        jfl.AssetFromJar("ej.mobile.all.min.js")
        jfl.AssetFromJar(
    "ej.unobtrusive.min.js")
        
    'jfl.AssetFromJar("ej.widget.angular.min.js")
        'jfl.assetfromjar("ej.widget.ko.min.js")
        'jfl.AssetFromJar("excanvas.min.js")
        jfl.AssetFromJar("jquery.easing.1.3.min.js")
        jfl.AssetFromJar(
    "jquery-3.1.1.min.js")
        jfl.AssetFromJar(
    "jsrender.min.js")
        
    'jfl.AssetFromJar("knockout.min.js")
    If you recall from above, when I init the page, I show the user a progress dialog, this can be turned on and off from the library by the way. Then each file is copied using assetfromjar, which is...

    Code:
    Public Sub AssetFromJar(FileName As StringAs Boolean
        FileName = FileName.tolowercase
        
    Try
            
    If File.Exists(targetFolder, FileName) = False Then
                
    Dim out As OutputStream = File.OpenOutput(targetFolder, FileName, False)
                
    File.Copy2(LoadFileFileFromJar(FileName), out)
                out.Close
                
    Return True
            
    Else
                
    Return True    ' File OK anyway
            End If
        
    Catch
            
    Log("Failed to copy file to Assets: " & FileName)
            
    Return False
        
    End Try
    End Sub
    I will include the tweaked version of this module here too, and finally...
     
  8. Mashiane

    Mashiane Expert Licensed User

    10. Compile to Library, your jar and xml files will be saved in the additional libraries folder. For comments in the xml file, write some comments on your b4a code.

    10.1 After your library is compiles, go to the libraries folder, rename the extension of your file from .jar to .zip
    10.2 Double click the newly named .zip file and then add your jss and css files on the root of the library as depicted below.

    library.png

    Close the archiver and then rename your library file back to .jar file. Congratulations, you are done. Now create a project, reference your library and then develop the app you want based on the HTML, JavaScript and CSS library you just created.

    That is how I created the AMTileView library.

    Ta! Enjoy..

    PS: Javascript/CSS libraries done in this fashion are a little slow (depending on the size of the js library you want to wrap) as they don't provide your native look and feel to your app. Yes there are some nice looking components you can use depending on what javascript/jquery framework you are looking at, but then I like the fact that you can trap events, change components of HTML elements from b4a.
     
    Last edited: Feb 3, 2017
    eps likes this.
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