B4A Library PageTurnView library providing a page turn animation

This library displays bitmap images and provides a page turn animation to allow the user to "turn" the pages.

This library wraps an Android view which written by Harri Smått and released as open source under the Apache 2.0 licence. It was located for Basic4android use by forum member Smee.

There is no credit due to me for the functionality of this library. As Harri wrote it as a normal Android view I have merely wrapped Erel's view structure around it to make it accessible to Basic4android.

Belated warning in 2021! Use Release mode. You can probably use legacy debug mode if you need to, but normal debug mode will not work with this library.

EDIT :- Version 1.1 posted. See post #6 for details.

EDIT :- Version 1.2 posted. See post #10 for details.

EDIT :- Version 1.3 posted. See post #43 for details.

EDIT :- Version 1.4 posted. See post #158 for details.
 

Attachments

  • PageTurnView1.4.zip
    38.6 KB · Views: 760
Last edited:

Rusty

Well-Known Member
Licensed User
Longtime User
Great functionality.
Is there a way to display, for example: page two on the left page while page three is on the right page?
sequence:
Page one is on the right, turn the page, the page 2 is on the left and page 3 appears on the right so that both the left and right pages show different (and new) images.
thanks,
Rusty
 

Rusty

Well-Known Member
Licensed User
Longtime User
Any replies to my above question? or is there another library that supports such a function?
Thanks,
Rusty
 

Rajesh kannan MJ

Member
Licensed User
Longtime User
Hi,

When trying to view your sample app, I am getting error message. Please see attached image,

I am new to B4A,

Thanks,
 

Attachments

  • exceptionx.jpg
    exceptionx.jpg
    44.1 KB · Views: 305

Rajesh kannan MJ

Member
Licensed User
Longtime User
Please ignore my previous question. I found that the "exceptionex" error was due to "threading" library. I downloaded the library and included it. And the demo works super cool,

Thanks for this library,
 

tpakis

Active Member
Licensed User
Longtime User
@agraham Or a new paginator function to get only the text (not the bitmap) of a page so we can draw it on canvas with drawtext (this works fine)
 
Last edited:

murdoch1976

Member
Licensed User
Longtime User
I'm also getting a null pointer error. In an "Activity Create" sub I'm not getting any further than the following two lines of code...

B4X:
    PageTurner.Initialize("PageTurner", 20)
    Activity.AddView(PageTurner, 0dip, 0dip, Activity.Width, Activity.Height)

I can't try / catch the error, it simply bombs out. "Unfortunately <App Name> has stopped." appears on the screen of the device I'm testing on (Sony Xperia Z3 Compact).

There is some explanation of the error in the logs which I'll paste below, and you said to a previous person who had reported the same error that it's something to do with being "OnResume" or "OnPause" - but it's neither. This is all occurring during the Activity_Create event, so how (and why) would the resume event be getting triggered? Someone help me pleeeease!?! My app used to work fine about 18 months ago, and I've only recently picked it up again, and "kapow" nothingness.

** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **
** Activity (flipper) Create, isFirst = true **
** Activity (flipper) Resume **
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Integer.intValue()' on a null object reference
at anywheresoftware.b4a.agraham.pageturnview.CurlViewWrapper.getBitmapCount(CurlViewWrapper.java:140)
at anywheresoftware.b4a.agraham.pageturnview.CurlView.updateBitmaps(CurlView.java:652)
at anywheresoftware.b4a.agraham.pageturnview.CurlView.onPageSizeChanged(CurlView.java:178)
at anywheresoftware.b4a.agraham.pageturnview.CurlRenderer.updatePageRects(CurlRenderer.java:235)
at anywheresoftware.b4a.agraham.pageturnview.CurlRenderer.onSurfaceChanged(CurlRenderer.java:135)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1511)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1239)
** Activity (flipper) Pause, UserClosed = true **
 

murdoch1976

Member
Licensed User
Longtime User
Actually, forget that, sorry. It turned out it was crashing as the pic it was meant to then display hadn't copied from the assets folder. This is due to all this new-fangled "virtual asset" folder lark (yes, it's been quite a while since I used B4A last), which is all very new to me.

A lot has changed has it not.

Sorry for bothering anyone with my noob musings.
 

tpakis

Active Member
Licensed User
Longtime User
@agraham any chance on an update for the hollow text bug? I think (and hope) it should be a change in one line from setStyle(Paint.Style.STROKE) to setStyle(Paint.Style.FILL).
 

tpakis

Active Member
Licensed User
Longtime User
The only solution to the bug above, that i could find (because this is an excellent and very useful library) was to replace the pager (and not use the one in the library) and its methods. So if you need the pager use these functions to paginate, get the page count and get the page bitmap to show in the pageturview, don't use the pager object from the library. It needs the javaobject library so don't forget to add in Process_Globals: Dim nativeMe As JavaObject and in Activity_Create: If FirstTime Then nativeMe.InitializeContext End If. The java code is from Agraham's library with minor changes (most important the paint style). One last thing: in SetPageParameters2 (java code) the text alignment is set to Layout.Alignment.ALIGN_CENTER because i need it that way, if you want you can change it to Layout.Alignment.ALIGN_NORMAL or whatever you like.

B4X:
public Sub SetPaintParamsNew(fontss As Typeface,fontsizes As Float,Colorss As Int,antialliass As Boolean)
Dim lv As LayoutValues
lv = GetDeviceLayoutValues
Dim f As Float = lv.Scale
nativeMe.RunMethod("SetPaintParameters2", Array(fontss,fontsizes,f,Colorss,antialliass))
End Sub

public Sub SetPageParamsNew(widths As Int,leftmarg As Int,heights As Int,topmarg As Int,linespaces As Float)
nativeMe.RunMethod("SetPageParameters2", Array(widths,leftmarg,heights,topmarg,linespaces))
End Sub


public Sub PaginateNew(text As String)
nativeMe.RunMethod("Paginate2", Array(text))
End Sub


public Sub GetPageBitmapNew(indexs As Int, backcolors As Int) As Bitmap
Dim a As Bitmap
a= nativeMe.RunMethod("GetPageBitmap2", Array(indexs,backcolors))
Return a
End Sub

public Sub GetPagecountNew As Int
Dim a As Int
a = nativeMe.RunMethod("getPageCount2",Null)
Return a

End Sub
#If JAVA

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Typeface;
import android.text.Layout;
import android.text.Layout.Alignment;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.util.DisplayMetrics;
import java.util.Vector;


    private Vector<String> listOfPages = new Vector();
    private TextPaint txtpaint;
    private int width;
    private int leftmargin;
    private int height; private int topmargin; private Layout.Alignment alignment; private float spacingmult = 1.0F;
    private float spacingadd = 0.0F;

    public void SetPageParameters2(int width, int leftmargin, int height, int topmargin, float linespacing)
    {
      this.width = width;
      this.height = height;
      this.leftmargin = leftmargin;
      this.topmargin = topmargin;
      this.alignment = Layout.Alignment.ALIGN_CENTER;
      spacingmult = linespacing;
    }
  
    public void SetPaintParameters2(Typeface typeface, float textsize, float scales, int color, boolean antialias)
    {
      txtpaint = new TextPaint();
      txtpaint.setTextSize(textsize * scales);
      txtpaint.setTypeface(typeface);
      txtpaint.setColor(color);
      txtpaint.setAntiAlias(antialias);
      txtpaint.setStrokeWidth(0.0F);
      txtpaint.setStyle(Paint.Style.FILL);
    }
  
    public void Paginate2(String text)
    {
     listOfPages.clear();
      int index1 = 0;int index2 = 0;
      if (Character.getNumericValue(text.charAt(text.length() - 1)) != 10) {
        text = text + "\n";
      }
    
      StaticLayout layout = new StaticLayout(text, txtpaint, width - leftmargin * 2, alignment, spacingmult, spacingadd, false);
      int totalLines = layout.getLineCount();
      int linePerPage = layout.getLineForVertical(height - topmargin * 2);
      int i = 0;
      do
      {
        int line = Math.min(linePerPage * (i + 1) - 1, totalLines - 1);
        index2 = layout.getOffsetForHorizontal(line, width - leftmargin * 2);
        String sub = text.substring(index1, index2);
      
        index1 = index2;
        listOfPages.add(sub);
        i++;
      } while (index2 < text.length() - 1);
    }
  
    public Bitmap GetPageBitmap2(int index, int backcolor)
    {
      Bitmap pagebmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
      Bitmap textbmp = Bitmap.createBitmap(width - leftmargin * 2, height - topmargin * 2, Bitmap.Config.ARGB_8888);
      Canvas ctext = new Canvas(textbmp);
      StaticLayout layout = new StaticLayout((CharSequence)listOfPages.elementAt(index), txtpaint, width - leftmargin * 2,
        alignment, spacingmult, spacingadd, false);
      layout.draw(ctext);
      Canvas cpage = new Canvas(pagebmp);
      cpage.drawColor(backcolor);
      cpage.drawBitmap(textbmp, leftmargin, topmargin, txtpaint);
      return pagebmp;
    }
  
    public int getPageCount2()
    {
      return listOfPages.size();
    }
  
    public final Layout.Alignment ALIGN_CENTER = Layout.Alignment.ALIGN_CENTER;
  
    public final Layout.Alignment ALIGN_NORMAL = Layout.Alignment.ALIGN_NORMAL;
  
    public final Layout.Alignment ALIGN_OPPOSITE = Layout.Alignment.ALIGN_OPPOSITE;


#End If
 

AnandGupta

Expert
Licensed User
Longtime User
I am starting development on B4A a bit late, one year after buying it, so please excuse me if I do not know some obvious basic of B4A development.

I am reading the forum now and download and check demo which interest me. PageTurnView is one of this.

Unfortunately I am getting error as below when compiling PageTurnViewDemo,

LogCat connected to: emulator-5554
--------- beginning of /dev/log/main--------- beginning of /dev/log/system~i:** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
java.lang.NullPointerException
at anywheresoftware.b4a.agraham.pageturnview.CurlViewWrapper.getBitmapCount(CurlViewWrapper.java:140)
at anywheresoftware.b4a.agraham.pageturnview.CurlView.updateBitmaps(CurlView.java:652)
at anywheresoftware.b4a.agraham.pageturnview.CurlView.onPageSizeChanged(CurlView.java:178)
at anywheresoftware.b4a.agraham.pageturnview.CurlRenderer.updatePageRects(CurlRenderer.java:235)
at anywheresoftware.b4a.agraham.pageturnview.CurlRenderer.onSurfaceChanged(CurlRenderer.java:135)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1512)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)
** Activity (main) Pause, UserClosed = true **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
java.lang.NullPointerException
at anywheresoftware.b4a.agraham.pageturnview.CurlViewWrapper.getBitmapCount(CurlViewWrapper.java:140)
at anywheresoftware.b4a.agraham.pageturnview.CurlView.updateBitmaps(CurlView.java:652)
at anywheresoftware.b4a.agraham.pageturnview.CurlView.onPageSizeChanged(CurlView.java:178)
at anywheresoftware.b4a.agraham.pageturnview.CurlRenderer.updatePageRects(CurlRenderer.java:235)
at anywheresoftware.b4a.agraham.pageturnview.CurlRenderer.onSurfaceChanged(CurlRenderer.java:135)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1512)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)
** Activity (main) Pause, UserClosed = true **


I read this message thread and found #131 https://www.b4x.com/android/forum/t...-page-turn-animation.10795/page-7#post-164509
which points similar problem but could not understand the solution, if any.

Please guide me if I need to download any library or files for it.

I am using PageTurnView and Threading, as discussed here, see screen shot attached.
2016-10-10_223357.png

Regards,

Anand
 
Last edited:

Smee

Well-Known Member
Licensed User
Longtime User
I guess you have set your library locations up in preferences and the ide knows where the library is? If you are running the demo it should work as long as the files can be accessed
 

AnandGupta

Expert
Licensed User
Longtime User
Thanks for the reply.

Obviously I am missing something but what !!

I am attaching the screen shots of the path preference, ide library view, compile and run AVD view, run error log view. Please see and suggest remedy.

2016-10-14_232253.png 2016-10-14_232413.png 2016-10-14_232620.png 2016-10-14_232633.png

I am unable to understand what to do next to get it working. I am ready to give more information if required.

Please guide.

Regards,

Anand
 

AnandGupta

Expert
Licensed User
Longtime User
Looking for a solution to the error, I found https://www.b4x.com/android/forum/t...terexception-null-receiver.70501/#post-447799 where Erel pointed that "This is a debugger error. What happens in release mode?"

I got the idea and changed the build to release and lo and behold it WORKS !! Since I have touch screen laptop, I can very well check it in AVD. :)

So this problem is CLOSED and thanks for this forum.

But I will request Erel or someone who can, to check it in both debug and release and fix the unnecessary error in debug. It is creating problem in debugging such samples / projects.

Regards,

Anand
 

jchal

Active Member
Licensed User
Longtime User
i tryed to run the example but i got the following why?
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
java.lang.NullPointerException
at anywheresoftware.b4a.agraham.pageturnview.CurlViewWrapper.getBitmapCount(CurlViewWrapper.java:140)
at anywheresoftware.b4a.agraham.pageturnview.CurlView.updateBitmaps(CurlView.java:652)
at anywheresoftware.b4a.agraham.pageturnview.CurlView.onPageSizeChanged(CurlView.java:178)
at anywheresoftware.b4a.agraham.pageturnview.CurlRenderer.updatePageRects(CurlRenderer.java:235)
at anywheresoftware.b4a.agraham.pageturnview.CurlRenderer.onSurfaceChanged(CurlRenderer.java:135)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1513)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1248)
** Activity (main) Pause, UserClosed = true **
 

adflconsultingSrL

New Member
Licensed User
Hello ,
I'm using the "PageTurnView" library very simple to use, question and can display two different images, one on the right, and the other on the left?
Some advice to solve the problem, thank you so much,
Greetings, Fabrizio
 

jimmyF

Active Member
Licensed User
Longtime User
** Activity (main) Pause, UserClosed = true **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Integer.intValue()' on a null object reference
at anywheresoftware.b4a.agraham.pageturnview.CurlViewWrapper.getBitmapCount(CurlViewWrapper.java:141)
at anywheresoftware.b4a.agraham.pageturnview.CurlView.updateBitmaps(CurlView.java:652)
at anywheresoftware.b4a.agraham.pageturnview.CurlView.onPageSizeChanged(CurlView.java:178)
at anywheresoftware.b4a.agraham.pageturnview.CurlRenderer.updatePageRects(CurlRenderer.java:235)
at anywheresoftware.b4a.agraham.pageturnview.CurlRenderer.onSurfaceChanged(CurlRenderer.java:135)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1555)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1270)

Got this same error running the sample code.
 
Top