Android Tutorial Wrapping a small and easy 3rd party library with java

Discussion in 'Tutorials & Examples' started by DonManfred, Mar 7, 2015.

  1. DonManfred

    DonManfred Expert Licensed User

    I wrote a small tutorial for @Johan Schoeman then... Then i thought this could be interesting to more than just Johan.

    So here we go:


    1.Original
    The content of the zip from Github

    2.Find the main source folder
    Find the folder from the LIB (if there are lib and demo) where the res-folder is

    3. use Rgenerator
    copy RGenerator.exe to this folder and run it (you find rgenerator.exe in forum)

    4.Cleanup
    remove not used parts

    5.spacer

    6.Start of a new Eclipse-project
    This is basically a copy of my HTMLTextView library. This is the base of all wraps i do usually...
    Note: Some parts of the file in de\donmanfred\ still needs to be updated to match "the current wrapper"

    So i prepare a new project directory structure

    Copy the folder Circularbutton to your Eclipse workspace
    in eclipse do a import of a available project, select the path of your workspace\Circularbutton
    Finish

    Now you are in eclipse
    After you have imported and opened your project we see some errors

    [​IMG]


    We will start with the R.java

    [​IMG]


    Use the Quickfix "Import 'BA' (anywheresoftware.b4a)"


    Next the system says the the r.java should get the right package.
    [​IMG]

    Add the suggested packagedeclaration

    Save the r.java. The errors should gone for this file now.

    [​IMG]

    Looking at the Errors we see an indicator for an higher android-version
    than we refer to at start (the base is using android SDK 8)

    So we change the Build-Paths and select a newer android.jar
    In this case i usually use android 15 (4.0.3+ or so) but for this wrapper we need to set
    android-sdk\platforms\android-16\android.jar

    After setting this error disappears too...

    I already said earlier that my wraps usually are based on HTMLTextView library.
    Some artefacts still are in the new wrappe we are writing

    To know what we need to change and to what
    we look at the java file from the lib (in this case it is just one). Here we find information
    of what object it goes...
    public class CircularButton extends ImageView {

    This lib is an CircularButton which is based on an ImageView.
    So basically it is a VIEW too.

    in the file de\donmanfred\Circularbutton.java

    we start to edit

    public class htmltv implements DesignerCustomView {
    will get changed to the new class we want

    public class CircularButtonWrapper implements DesignerCustomView {

    [​IMG]

    we now use the quickfix to let eclipse rename the file correct.

    Now:
    private HtmlTextView mtext;
    this is the relict we need to adapt

    we start with a new definition using the right objecttype
    private CircularButton cb;

    and use the quickfix to import

    [​IMG]

    after replacing all occurencies of mtext with cb
    we still have the line
    cb = new HtmlTextView(ba.context);

    change it to
    cb = new CircularButton(ba.context);

    to match the right objectdeclaration

    As we are extending a view here we use a viewwrapper
    here

    changing
    Code:
    public class CircularButtonWrapper implements DesignerCustomView {
    to
    Code:
    public class CircularButtonWrapper extends ViewWrapper<CircularButton> implements DesignerCustomView {
    Use the quickfix to import anywheresoftware.b4a.objects.ViewWrapper;

    from the libs github page we know that we need to allow changes


    Button color

    button.setButtonColor(Color.BLACK);

    Shadow color

    button.setShadowColor(Color.BLUE);

    in fact we need at least two methods to do this

    Code:
    public void setButtonColor(int color)   {
       
       
    }
     
       public void setShadowColor(int color)   {
       
       }

    now we fill life into it

    Code:
    public void setButtonColor(int color)   {
         cb.setButtonColor(color);
       
    }
     
       public void setShadowColor(int color)   {
         cb.setShadowColor(color);   
       }
    we need a helper more...

    Code:
    public void setImageBitmap(Bitmap bm)   {
         cb.setImageBitmap(bm);
         cb.invalidate();
       
    }
    now the a little bit tricky parts

    in the lib we see

    Code:
    public CircularButton(Context context, AttributeSet attrs, int defStyle) {
      super(context, attrs, defStyle);
      init(context, attrs);
      
    }
      @TargetApi(Build.VERSION_CODES.HONEYCOMB)
      private void init(Context context, AttributeSet attrs) {
      setScaleType(ScaleType.CENTER_INSIDE);
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
      setLayerType(View.LAYER_TYPE_SOFTWARE, null);
      }
      mButtonPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
      mButtonPaint.setStyle(Paint.Style.FILL);
      if (attrs != null) {
      TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircularButton);
      buttonColor = a.getColor(R.styleable.CircularButton_buttonColor, buttonColor);
      shadowColor = a.getColor(R.styleable.CircularButton_shadowColor, shadowColor);
      a.recycle();
      }
      setButtonColor(buttonColor);
      }
    R.styleable.CircularButton shows an error. The r.java is not 100% ok. In this code the lib will look
    into the xml definition of the styleable object Circularbutton.
    We dont want to use xml-files. So we try to replace them.
    Only two properties are available. We replace them with hardcoded values (leaving the defaults for now)

    Code:
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
      
    private void init(Context context, AttributeSet attrs) {
      setScaleType(ScaleType.CENTER_INSIDE);
      
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
      setLayerType(
    View.LAYER_TYPE_SOFTWARE, null);
      
    }
      mButtonPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
      mButtonPaint.setStyle(Paint.Style.FILL);
      setButtonColor(buttonColor);
      }

    back to the "own" file

    Adapting
    Code:
    @Version(1.00f)
    @ShortName(
    "Circularbutton")
    to set the correct object and libraryversion when using b4a later.

    Now we are in a stage with no errors. As i´m writing this text here i am not sure if it works...

    Let´s try it

    [​IMG]

    and click on compile... when you have a look at this BIG xml-file you see that we need to exclude the original references....

    Add

    ,me.alexrs
    ^ comma
    at the end of the -b4aignore line... me.alexxrs is the classpath of the original-library we are wrapping.

    compile again

    Now the xml looks much better. no not needed references.

    At this point i will do a test b4a-project (10.Example.zip)


    Last but not least: A spoiler :D

    [​IMG]
     

    Attached Files:

  2. Johan Schoeman

    Johan Schoeman Expert Licensed User

    Thank you @DonManfred. You have spoiled us delux......!:)
     
    ghloo_sa32 and DonManfred like this.
  3. thedesolatesoul

    thedesolatesoul Expert Licensed User

    This is very comprehensive :)
    You can format it a bit, and maybe add some more information (like @dependson) when you have time.
    Good job.
     
    ghloo_sa32, Peter Simpson and NJDude like this.
  4. Johan Schoeman

    Johan Schoeman Expert Licensed User

    Tried my luck with the wrapper "boss" (@DonManfred) for some additional info. He told me to sort it out myself else we learn nothing....:)

    So, now I have 4 buttons with click events that are working. But it took me a while to get there....
     

    Attached Files:

    DonManfred likes this.
  5. thedesolatesoul

    thedesolatesoul Expert Licensed User

    True. There is a long way to go to learn for all of us.
     
  6. Johan Schoeman

    Johan Schoeman Expert Licensed User

    The following with permission of @DonManfred.

    See attached project. Have added code to the library and recompiled the library to allow click events to be handled for circular buttons in B4A. Library files (circularbutton.jar and circularbutton.xml) are in the /files folder of the project. Copy them to your additional library folder.

    The attached project and library and/or any of its derivatives that are used in B4X (B4A, B4J, B4I) is Donationware. You can download the library, you can test the library. But if you want to USE the library in your App you need to Donate for it. Please click on the Donate button to donate (You can donate any amount you want for the work that @DonManfred has done to create this library - the link attached to the below Donate button belongs to @DonManfred)

    [​IMG]

    Edit: CircularButton_1.zip added. Just so that the circular buttons vibrate when you click on them. Makes use of fiddleAround (jar and xml). They are in the /files folder of the project. Copy them to additional library folder (Same Donationware principle applies to this project)
     

    Attached Files:

    Last edited: Mar 7, 2015
  7. cimperia

    cimperia Active Member Licensed User

    I am testing the library.

    It works fine until I use the bringToFront method. You can reproduce the error with following code:

    Code:
    Activity.LoadLayout("main")
    Dim ccb As Circularbutton  
    ccb.Initialize(
    "")
    ccb.AddToParent(
    Activity10dip20dip50dip100dip)
    ccb.BringToFront
    The app crashes with:

    Code:
    ** Activity (main) Create, isFirst = true **

      Error occurred on line: 
    41 (main)

      java.lang.RuntimeException: Object should first be initialized (Circularbutton).
       at anywheresoftware.b4a.AbsObjectWrapper.getObject(AbsObjectWrapper.java:
    49)
       at anywheresoftware.b4a.objects.ViewWrapper.BringToFront(ViewWrapper.java:
    250)
       at java.lang.reflect.Method.invokeNative(Native Method)
       at java.lang.reflect.Method.invoke(Method.java:
    525)
       at anywheresoftware.b4a.shell.Shell.runVoidMethod(
    Shell.java:680)
       at anywheresoftware.b4a.shell.Shell.raiseEventImpl(
    Shell.java:308)
       at anywheresoftware.b4a.shell.Shell.raiseEvent(
    Shell.java:238)
       at java.lang.reflect.Method.invokeNative(Native Method)
       at java.lang.reflect.Method.invoke(Method.java:
    525)
       at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:
    121)
       at b4a.example.main.afterFirstLayout(main.java:
    100)
       at b4a.example.main.access$
    100(main.java:17)
       at b4a.example.main$WaitForLayout.run(main.java:
    78)
       at android.os.Handler.handleCallback(Handler.java:
    800)
       at android.os.Handler.dispatchMessage(Handler.java:
    100)
       at android.os.Looper.loop(Looper.java:
    194)
       at android.app.ActivityThread.main(ActivityThread.java:
    5431)
       at java.lang.reflect.Method.invokeNative(Native Method)
       at java.lang.reflect.Method.invoke(Method.java:
    525)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:
    833)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:
    600)
       at dalvik.system.NativeStart.main(Native Method)
    ** 
    Activity (main) Resume **
    Any idea on how to fix this?

    Thanks
     
  8. Johan Schoeman

    Johan Schoeman Expert Licensed User

    The "BringToFront" call that you are using is probably related to the customeview itself. I seem to recall that this is not one of the methods in the library. Only setButtonVolor, setShadowColor, and setImageBitmap is methods supported by the library.
     
  9. giga

    giga Well-Known Member Licensed User

    @DonManfred
    This took you some time and I am sure everyone appreciates it. Including myself :)
     
    DonManfred likes this.
  10. hogiebaer

    hogiebaer Active Member Licensed User

    Many many thx for your excellent work, donmanfred !!!!!!

    Greetz
    Holger
     
  11. Brian Robinson

    Brian Robinson Active Member Licensed User

    Excellent work.

    I have been too lazy and busy to read up on the documentation and then go through all the trial and error to create libs, but with this excellent guide I think I will have a crack at it.

    Thanks for the time you put into it.
     
  12. moster67

    moster67 Expert Licensed User

    Maybe this should be a "sticky" in the 'Libraries developers questions' section?
     
  13. MarcoRome

    MarcoRome Expert Licensed User

    Really Super Work.
    Thank you Don for your work
     
  14. Bel

    Bel Active Member Licensed User

    Hi
    I can wrapper fist library (CicularButton) and export it jar file
    I use example current post attachment
    but when i select it in basic4android get bellow error
    @DonManfred please help me i need to it

    [​IMG]
     
  15. DonManfred

    DonManfred Expert Licensed User

    add "me.alexrs" to b4-ignore when compiling with slc
     
  16. Bel

    Bel Active Member Licensed User

    Thanks
    I test it but again get error
    I compile it with eclipse (because when i use simple library compiler,cannot compile and get below error)
     
  17. Bel

    Bel Active Member Licensed User

  18. Johan Schoeman

    Johan Schoeman Expert Licensed User

    If you use the attached to compile it with Simple Library Compiler (SLC) then it should compile. Follow this:
    1. Extract the zip folder - the folder structure look as follows:
    Bel
    bin (just ignore this folder - you can delete it but it will be recreated when the library compiles)
    src
    circularbuttonwrapper
    CircularButtonWrapper.java​
    com
    circularbutton
    CircularButton.java
    R.java​

    2. Start Simple Library Compiler
    3. Click on Browse and then browse until you get to the folder called Bel (see structure above)
    4. Click on Bel once you have found it - It will be added to the Project Folder field of SLC
    5. In the Library Name field of SLC you type in CircularButton
    6. In the -b4aignore field of SLC you type in com
    7. Click on Compile
     

    Attached Files:

    • Bel.zip
      File size:
      17.2 KB
      Views:
      114
    fredo likes this.
  19. DonManfred

    DonManfred Expert Licensed User

    to import android.annotation.TargetApi you need to reference a higher anroid.jar in eclipse in the Build-Settings of your project than the one you are using.

    [​IMG]
     
  20. Bel

    Bel Active Member Licensed User

    Thank my friends
    I download attach example and compile with slc but again it get error
    Problem is android.annotation.TargetApi
    How do i reference a higher android.jar in eclipse while i use slc and dont use eclipse
    what's problem my dear friends?
     
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