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

DonManfred

Expert
Licensed User
I am going to try and wrap this (CircularButton) from here
https://github.com/Alexrs95/Circula...alexrs/circularbutton/lib/CircularButton.java
Found it on the android-arsenal.com website. Will in all probability call on wrapper Doctor @DonManfred's help to work through this :)....that is if you don't mind....
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




We will start with the R.java




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


Next the system says the the r.java should get the right package.


Add the suggested packagedeclaration

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



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 {



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



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
B4X:
public class CircularButtonWrapper implements DesignerCustomView {
to
B4X:
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

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

now we fill life into it

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

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

in the lib we see

B4X:
  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)

B4X:
  @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
B4X:
@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



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

 

Attachments

Johan Schoeman

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.
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....
 

Attachments

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)



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)
 

Attachments

Last edited:

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:

B4X:
Activity.LoadLayout("main")
Dim ccb As Circularbutton  
ccb.Initialize("")
ccb.AddToParent(Activity, 10dip, 20dip, 50dip, 100dip)
ccb.BringToFront
The app crashes with:

B4X:
** 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
 

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.
 

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.
 

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

 

Bel

Active Member
Licensed User
add "me.alexrs" to b4-ignore when compiling with slc
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)
Starting step: Compiling Java code.
javac 1.8.0_40
C:\Users\User\workspace\CicularButton\src\me\alexrs\circularbutton\lib\CircularButton.java:3: error: package android.annotation does not exist
import android.annotation.TargetApi;
^
1 error


Error.
 

Johan Schoeman

Expert
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)
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
 

Attachments

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?
 
Top