B4A Library Zoomage - A simple pinch-to-zoom Library

This is a shortwrap for this Github-Project.

- The Apps needs to be AppCompat compatible as the Zoomage extends an AppCompat Imageview
- The Image should be place in a path readable by the app. It seems not to work with Assets. I did not tried it much; if i copy it first to a save path it works for me.


Version: 0.1
  • ZoomageView
    • Fields:
      • ba As BA
    • Functions:
      • BringToFront
      • DesignerCreateView (base As Panel, lw As Label, props As Map)
      • Initialize (EventName As String)
      • Invalidate
      • Invalidate2 (arg0 As android.graphics.Rect)
      • Invalidate3 (arg0 As Int, arg1 As Int, arg2 As Int, arg3 As Int)
      • IsInitialized As Boolean
      • RemoveView
      • RequestFocus As Boolean
      • reset
        Reset image back to its original size. Will snap back to original size
        if animation on reset is disabled via {@link #setAnimateOnReset(boolean)}.
      • reset2 (animate As Boolean)
        Reset image back to its starting size. If {@code animate} is false, image
        will snap back to its original size.
        animate: animate the image back to its starting size
      • SendToBack
      • SetBackgroundImage (arg0 As android.graphics.Bitmap) As BitmapDrawable
      • SetColorAnimated (arg0 As Int, arg1 As Int, arg2 As Int)
      • SetLayout (arg0 As Int, arg1 As Int, arg2 As Int, arg3 As Int)
      • SetLayoutAnimated (arg0 As Int, arg1 As Int, arg2 As Int, arg3 As Int, arg4 As Int)
      • setScaleRange (minScale As Float, maxScale As Float)
        Set the minimum and maximum allowed scale for zooming. {@code minScale} cannot
        be greater than {@code maxScale} and neither can be 0 or less. This will result
        in an {@link IllegalStateException}.
        minScale: minimum allowed scale
        maxScale: maximum allowed scale
      • SetVisibleAnimated (arg0 As Int, arg1 As Boolean)
    • Properties:
      • AnimateOnReset As Boolean
        Returns status of animateOnReset. This causes the image to smoothly animate back
        to its start position when reset. Default value is true.
      • AutoCenter As Boolean
        Whether or not the image should automatically center itself when it's dragged partially or
        fully out of view.
      • AutoResetMode As Int
        Get the current {@link AutoResetMode} mode of the image. Default value is {@link AutoResetMode#UNDER}.
      • Background As android.graphics.drawable.Drawable
      • Color As Int [write only]
      • CurrentScaleFactor As Float [read only]
        Get the current scale factor of the image, in relation to its starting size.
      • DoubleTapToZoom As Boolean
        Gets double tap to zoom state.
      • DoubleTapToZoomScaleFactor As Float
        Gets the double tap to zoom scale factor.
      • Enabled As Boolean
      • Height As Int
      • ImageBitmap As android.graphics.Bitmap [write only]
      • ImageDrawable As android.graphics.drawable.Drawable [write only]
      • ImageURI As String [write only]
      • Left As Int
      • Padding As Int()
      • Parent As Object [read only]
      • RestrictBounds As Boolean
        If restricted bounds are enabled, the image will not be allowed to translate
        farther inward than the edges of the view's bounds, unless the corresponding
        dimension (width or height) is smaller than those of the view's frame.
      • Tag As Object
      • Top As Int
      • Translatable As Boolean
        Returns whether the image is translatable.
      • Visible As Boolean
      • Width As Int
      • Zoomable As Boolean
        Returns the zoomable state of the image.

An Example can be downloaded HERE due to it´s size.


  • zoomageV0.1.zip
    30.3 KB · Views: 556
  • zoomageSRC.zip
    2.9 KB · Views: 455


Licensed User
You should ALWAYS(!!!) start a NEW Thread for any Issue you have.

Note that the issue is not related to this lib.


Licensed User
The Image should be place in a path readable by the app. It seems not to work with Assets. I did not tried it much; if i copy it first to a save path it works for
You did a really good job with this lib. You documented everything well. I was able to use the Assets folder as shown in my below code without having to save the file from assets to defaultExternal. It works well. I can zoom in and out. If, what I did does not make sense, please correct accordingly:
Sub Activity_Create(FirstTime As Boolean)
    Dim bd As BitmapDrawable
    bd.Initialize(LoadBitmap(File.DirAssets, "empire.jpg"))
    bd.Gravity = Gravity.FILL
End Sub


Licensed User
It seems not to work with Assets
Here is another way of achieving the same result as above without having to save the bitmap file to DefaultExternal, even shorter than the one in post #11:
Sub Activity_Create(FirstTime As Boolean)
    ZoomageView1.ImageBitmap=LoadBitmap(File.DirAssets, "empire.jpg")   
End Sub

Ibrahim Saleh

Licensed User
This Library is not working for me, when trying to open the example app on device it shows the current error log:

Logger connected to: 0440333965138950
--------- beginning of crash
--------- beginning of system
--------- beginning of main
Service started in the background. Trying to start again in foreground mode.
*** Service (starter) Create ***
** Service (starter) Start **
Service started in foreground mode.
** Activity (main) Create, isFirst = true **
main_activity_create (java line: 351)
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at anywheresoftware.b4a.keywords.LayoutBuilder.loadLayout(LayoutBuilder.java:170)
at anywheresoftware.b4a.objects.ActivityWrapper.LoadLayout(ActivityWrapper.java:209)
at b4a.example.main._activity_create(main.java:351)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:213)
at b4a.example.main.afterFirstLayout(main.java:105)
at b4a.example.main.access$000(main.java:17)
at b4a.example.main$WaitForLayout.run(main.java:83)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6758)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:497)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:912)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.objects.CustomViewWrapper.AfterDesignerScript(CustomViewWrapper.java:64)
at anywheresoftware.b4a.keywords.LayoutBuilder.loadLayout(LayoutBuilder.java:162)
... 14 more
Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/jsibbold/zoomage/ZoomageView;
at de.donmanfred.ZoomageViewWrapper._initialize(ZoomageViewWrapper.java:59)
... 17 more
Caused by: java.lang.ClassNotFoundException: com.jsibbold.zoomage.ZoomageView
at java.lang.VMClassLoader.findLoadedClass(Native Method)
at java.lang.ClassLoader.findLoadedClass(ClassLoader.java:738)
at java.lang.ClassLoader.loadClass(ClassLoader.java:363)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
... 18 more
Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v7/widget/AppCompatImageView;
... 18 more
Caused by: java.lang.ClassNotFoundException: Didn't find class "android.support.v7.widget.AppCompatImageView" on path: DexPathList[[zip file "/system/framework/org.apache.http.legacy.boot.jar", zip file "/data/app/b4a.example-eRznNUjYDQLaQU7HhXHgIg==/base.apk"],nativeLibraryDirectories=[/data/app/b4a.example-eRznNUjYDQLaQU7HhXHgIg==/lib/arm, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134)
at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
... 18 more