B4A Library [Lib] ScrollView2D

Discussion in 'Additional libraries, classes and official updates' started by Informatix, Jul 4, 2012.

  1. Informatix

    Informatix Expert Licensed User

    Hello,

    Does it need a long explanation ? You can scroll in the two directions.

    This lib does not work with Android versions < 2.

    v1.01:
    I fixed a big bug in the original code.
    I added the function SmoothScrollTo.

    v1.02:
    I restarted from a fresh basis because of the many bugs in the original code. I fixed most of them (now, multitouch events and hardware keys are correctly handled) but a few are left and need more work (sometimes the wrong object get the focus and resizing is not perfectly handled). I noticed by the way that the stock scrollview is bugged and does not set the focus correctly if you move your finger very slowly.
    Thanks to Erel, I solved the problem with the B4A documentation.
    I added a new function: FullScroll.

    v1.03:
    I fixed all known bugs (including bugs found in ScrollView & HorizontalScrollView);
    I added the scrollbars;
    I added three new functions:
    - ScrollbarsVisibility
    - FadingEdges
    - GiveFocusToFirstVisible.

    v1.1:
    I fixed a problem with events that were not fired if declared in a class;
    I added two functions: ScrollingIsFinished and DisableTouchEventInterception.

    v1.2:
    SV2D appears now as a custom view in the designer with all its properties.

    v1.3:
    I fixed a bug (SV_2 = SV_1 did not work because the inner panel was declared in the wrong class).

    Enjoy,
    Fred
     

    Attached Files:

    Last edited: Jul 29, 2016
  2. Informatix

    Informatix Expert Licensed User

    v1.01:
    I fixed a big bug in the original code.
    I added the function SmoothScrollTo.

    I plan to add the FullScroll function in the next version and create a special version compatible with Android 1 (if someone is interested).
     
  3. JoanRPM

    JoanRPM Active Member Licensed User

    Thanks.
    Works fine in Android 4.0.3.
    Regards.
     
  4. Tom Christman

    Tom Christman Active Member Licensed User

    :sign0098:Thanks, it works on a gTablet running Honeycomb.
    Tom
     
  5. mc73

    mc73 Well-Known Member Licensed User

    Fails on my Samsung Galaxy S. It just hangs. Perhaps it has to do with my os version? 2.2.2. rooted.
     
  6. derez

    derez Expert Licensed User

    Great library !
    Can you please change the args in some of the methods to names which describe the use of the argument ? (like in setlayout, setbackground image)
     
  7. Informatix

    Informatix Expert Licensed User

    Does it hang when it starts ? When you scroll ?
    Try to remove the picture (the LoadBitmap line). Does it work now ?

    Your version is not the problem. The library has been compiled with API 7 and Froyo is built upon API 8.
     
  8. Informatix

    Informatix Expert Licensed User

    I'd like to change them but I don't know how to do that (without redeclaring everything). I suppose I have to add something to tell to B4A to add the View object documentation to my ScrollView documentation, but I don't know what. Erel ? :sign0085:
     
  9. Erel

    Erel Administrator Staff Member Licensed User

    Add this class to your code:
    Code:
    package anywheresoftware.b4a.objects;

    import java.io.IOException;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.util.HashMap;
    import java.util.Map;

    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.Rect;
    import android.graphics.drawable.BitmapDrawable;
    import android.graphics.drawable.Drawable;
    import android.graphics.drawable.GradientDrawable;
    import android.util.Log;
    import android.view.KeyEvent;
    import android.view.View;
    import android.view.ViewGroup;
    import android.view.animation.Animation;
    import android.widget.Button;
    import anywheresoftware.b4a.AbsObjectWrapper;
    import anywheresoftware.b4a.BA;
    import anywheresoftware.b4a.BALayout;
    import anywheresoftware.b4a.ObjectWrapper;
    import anywheresoftware.b4a.BA.Events;
    import anywheresoftware.b4a.BA.Hide;
    import anywheresoftware.b4a.BA.ShortName;
    import anywheresoftware.b4a.BALayout.LayoutParams;
    import anywheresoftware.b4a.keywords.Common;
    import anywheresoftware.b4a.objects.drawable.ColorDrawable;
    import anywheresoftware.b4a.objects.drawable.CanvasWrapper.BitmapWrapper;
    import anywheresoftware.b4a.objects.drawable.ColorDrawable.GradientDrawableWithCorners;

    @Hide
    @Events(values={
    "Click""LongClick"})
    public class ViewWrapper<T extends View> extends AbsObjectWrapper<T>{
       protected BA ba;
       @Hide
       public static int lastId;

       public void Initialize(final BA ba, String EventName) {
          innerInitialize(ba, EventName.toLowerCase(BA.cul), false);
       }
       @Hide
       public void innerInitialize(final BA ba, final String eventName, boolean keepOldObject) {
          this.ba = ba;
          getObject().setId(++lastId);
          if (ba.subExists(eventName + "_click")) {

             getObject().setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                   ba.raiseEvent(ViewWrapper.this.getObject(), eventName + "_click");
                }

             });
          }
          if (ba.subExists(eventName + "_longclick")) {
             getObject().setOnLongClickListener(new View.OnLongClickListener() {

                @Override
                public boolean onLongClick(View v) {
                   ba.raiseEvent(ViewWrapper.this.getObject(), eventName + "_longclick");
                   return true;
                }

             });
          }
          
       }
       /**
        * Gets or sets the background drawable.
        */
       public Drawable getBackground() {
          return getObject().getBackground();
       }
       public void setBackground(Drawable drawable) {
          getObject().setBackgroundDrawable(drawable);
       }
       public void SetBackgroundImage(Bitmap Bitmap) {
          anywheresoftware.b4a.objects.drawable.BitmapDrawable bd = new anywheresoftware.b4a.objects.drawable.BitmapDrawable();
          bd.Initialize(Bitmap);
          getObject().setBackgroundDrawable(bd.getObject());
       }
       /**
        * Invalidates the whole view forcing the view to redraw itself.
        *Redrawing will only happen when the program can process messages. Usually when it finishes running the current code. 
        */
       public void Invalidate() {
          getObject().invalidate();
       }
       /**
        * Invalidates the given rectangle.
        *Redrawing will only happen when the program can process messages. Usually when it finishes running the current code. 
        */
       public void Invalidate2(Rect Rect) {
          getObject().invalidate(Rect);
       }
       /**
        * Invalidates the given rectangle.
        *Redrawing will only happen when the program can process messages. Usually when it finishes running the current code. 
        */
       public void Invalidate3(int Left, int Top, int Right, int Bottom) {
          getObject().invalidate(Left, Top, Right, Bottom);
       }
       /**
        * Gets or sets the view's width.
        */
       public void setWidth(int width) {
          ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) getObject().getLayoutParams();
          lp.width = width;
          getObject().getParent().requestLayout();
       }
       public int getWidth() {
          return ((ViewGroup.LayoutParams)getObject().getLayoutParams()).width;
       }
       public int getHeight() {
          return ((ViewGroup.LayoutParams)getObject().getLayoutParams()).height;

       }
       public int getLeft() {
          BALayout.LayoutParams lp = (LayoutParams) getObject().getLayoutParams();
          return lp.left;
       }
       public int getTop() {
          BALayout.LayoutParams lp = (LayoutParams) getObject().getLayoutParams();
          return lp.top;
       }
       public void setHeight(int height) {
          ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) getObject().getLayoutParams();
          lp.height = height;
          getObject().getParent().requestLayout();
       }

       public void setLeft(int left) {
          BALayout.LayoutParams lp = (LayoutParams) getObject().getLayoutParams();
          lp.left = left;
          getObject().getParent().requestLayout();
       }

       public void setTop(int top) {
          BALayout.LayoutParams lp = (LayoutParams) getObject().getLayoutParams();
          lp.top = top;
          getObject().getParent().requestLayout();
       }
       /**
        * Sets the background of the view to be a ColorDrawable with the given color.
        *If the current background is of type GradientDrawable or ColorDrawable the round corners will be kept.
        */
       public void setColor(int color) {
          Drawable d = getObject().getBackground();
          if (d != null && d instanceof GradientDrawable) {
             float radius = 0;
             if (d instanceof GradientDrawableWithCorners) {
                radius = ((GradientDrawableWithCorners)d).cornerRadius;
             }
             else {
                GradientDrawable g = (GradientDrawable) getObject().getBackground();
                try {
                   Field state = g.getClass().getDeclaredField("mGradientState");
                   state.setAccessible(true);
                   Object gstate = state.get(g);
                   Field radiusF = gstate.getClass().getDeclaredField("mRadius");
                   radius = (Float) radiusF.get(gstate);
                   
                } catch (Exception e) {
                   Common.Log(e.toString());
                }
             }
             ColorDrawable cd = new ColorDrawable();
             cd.Initialize(color, (int)radius);
             getObject().setBackgroundDrawable(cd.getObject());
          }
          else {
             getObject().setBackgroundColor(color);
          }

       }
       public void setTag(Object tag) {
          getObject().setTag(tag);
       }
       /**
        * Gets or sets the Tag value. This is a place holder which can used to store additional data.
        */
       public Object getTag() {
          return getObject().getTag();
       }
       public void setVisible(boolean Visible) {
          getObject().setVisibility(Visible ? View.VISIBLE : View.GONE);
       }
       public boolean getVisible() {
          return getObject().getVisibility() == View.VISIBLE ? true : false;
       }
       public void setEnabled(boolean Enabled) {
          getObject().setEnabled(Enabled);
       }
       public boolean getEnabled() {
          return getObject().isEnabled();
       }
       /**
        * Changes the Z order of this view and brings it to the front.
        */
       public void BringToFront() {
          if (getObject().getParent() instanceof ViewGroup) {
             ViewGroup vg = (ViewGroup) getObject().getParent();
             vg.removeView(getObject());
             vg.addView(getObject());
          }
       }
       /**
        * Changes the Z order of this view and sends it to the back.
        */
       public void SendToBack() {
          if (getObject().getParent() instanceof ViewGroup) {
             ViewGroup vg = (ViewGroup) getObject().getParent();
             vg.removeView(getObject());
             vg.addView(getObject(), 0);
          }
       }
       /**
        * Removes this view from its parent.
        */
       public void RemoveView() {
          if (getObject().getParent() instanceof ViewGroup) {
             ViewGroup vg = (ViewGroup) getObject().getParent();
             vg.removeView(getObject());
          }
       }
       /**
        * Changes the view position and size.
        */
       public void SetLayout(int Left, int Top, int Width, int Height) {
          BALayout.LayoutParams lp = (LayoutParams) getObject().getLayoutParams();
          lp.left = Left;
          lp.top = Top;
          lp.width = Width;
          lp.height = Height;
          getObject().getParent().requestLayout();
       }
       /**
        * Tries to set the focus to this view.
        *Returns True if the focus was set.
        */
       public boolean RequestFocus() {
          return getObject().requestFocus();
       }
    }
     
  10. klaus

    klaus Expert Licensed User

    Thanks for this library.
    Works fine on my Nexus One.
    I added a version of the SQLiteDB_2D example using your library with a table.

    Best regards.
     
    Last edited: Jul 5, 2012
  11. moster67

    moster67 Expert Licensed User

    Very nice library!

    Tested on my HTC HD2 (Gingerbread) and Acer Iconia TAB A500 (ICS 4.03).

    Nice picture of your son too.

    :sign0098:
     
  12. Informatix

    Informatix Expert Licensed User

    Thanks a lot. :) Problem solved.
     
  13. mc73

    mc73 Well-Known Member Licensed User

    I really don't know. It just hangs even if I remove the picture.
     
  14. Erel

    Erel Administrator Staff Member Licensed User

    Check the unfiltered logs and see if there is any related message.
     
  15. WizardOz

    WizardOz Member Licensed User

    Great Lib! :sign0098:
     
  16. mc73

    mc73 Well-Known Member Licensed User

    Yes, there is an uncaught exception with onscrollchanged event.
    Code:
    >>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<<
    CheckJNI 
    is OFF
    creating instr width table
    --- registering native functions ---
    Starting 
    activityIntent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=flm.scrollview2d.demo/.main }
    onPause()
    Shutting down VM
    adbd disconnected
    WallpaperManager setVisibility visible true
    Start proc flm.scrollview2d.demo for activity flm.scrollview2d.demo/.main: pid=3282 uid=10080 gids={}
    WorkspaceDraw: Workspace drawWallpaperImage()
    Converting to boolean: TypedValue{t=0x3/d=0x593d "res/anim/accelerate_decelerate_interpolator.xml" a=1 r=0x10a0004}


    Converting to boolean: TypedValue{t=0x3/d=0x593d "res/anim/accelerate_decelerate_interpolator.xml" a=1 r=0x10a0004}
    Could not find method java.lang.String.<init>, referenced from method anywheresoftware.b4a.BA$1.uncaughtException


    VFY: unable to resolve direct method 1829: Ljava/lang/String;.<init> ([BLjava/nio/charset/Charset;)V
    VFY: replacing opcode 0x70 at 0x0033
    VFY: dead code 0x0036-003e in Lanywheresoftware/b4a/BA$1;.uncaughtException (Ljava/lang/Thread;Ljava/lang/Throwable;)V


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


    Could not find method anywheresoftware.b4a.BA.raiseEventFromUI, referenced from method flm.b4a.scrollview2d.ScrollView2DWrapper$MyScrollView.onScrollChanged


    VFY: unable to resolve virtual method 566: Lanywheresoftware/b4a/BA;.raiseEventFromUI (Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)V
    VFY: replacing opcode 0x6e at 0x002f


    wallpaper stop


    ** Activity (main) Resume **


    Displayed activity flm.scrollview2d.demo/.main: 396 ms (total 396 ms)


    onWindowFocusChanged(false)


    ACTION_BATTERY_CHANGED pluggedType: 2


    ACTION_BATTERY_CHANGED pluggedType: 2


    Event [ SCAN-RESULTS ]


    WPS-AP-AVAILABLE 


    No suitable AP found.
    CTRL-EVENT-NO-CONNECTION
    Event [WPS-AP-AVAILABLE ]
    Event [CTRL-EVENT-NO-CONNECTION]
    action: android.net.wifi.SHOW_AP_LIST_DIALOG


    showApDialog
    isShowingAccessPointListDialog():false


    setShowAccessPointListDialog():false
    ACTION_BATTERY_CHANGED pluggedType: 2


    ACTION_BATTERY_CHANGED pluggedType: 2


    ACTION_BATTERY_CHANGED pluggedType: 2


    ID[0]=0(1) Dn(0=>1)


    Ulight 3->7|0


    Dsptch > Window{482f0660 flm.scrollview2d.demo/flm.scrollview2d.demo.main paused=false}
    Shutting down VM
    threadid=1: thread exiting with uncaught exception (group=0x4001d7d0)
     
  17. Erel

    Erel Administrator Staff Member Licensed User

    Which version of Basic4android are you using? Make sure that there are no old copied of internal libraries in the additional libraries path.
     
  18. mc73

    mc73 Well-Known Member Licensed User

    Using 1.90 and avoiding to update libs at this particular point, since I have to make sure that the app I gave to my clients, runs stably, since this is my very first app at their field. I'm taking a close look to all updated libs, and of course b4a's new version, in order to feel more 'secure' about re-interpreting my app. I hope you understand me, Erel. Clients here are a bit aggressive :D
     
  19. Erel

    Erel Administrator Staff Member Licensed User

    This library requires v2.00.
     
  20. mc73

    mc73 Well-Known Member Licensed User

    I am using a webView for such procedures, thus, I guess I can wait a while :)
    By the way, my current libs' version are:
    core 1.90
    dialogs 2.80
    http 1.20
    jsinterface 1.30
    network 1.11
    phone 1.80
    randomaccessfile 1.30
    sql 1.02
    webviewextras 1.10

    Any way to make the update procedure simple or I just have to browse each library and check for an update? Just asking.
     
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