B4A Library AHViewPager library - Sliding panels now perfect

This library is a B4A implementation of the ViewPager object provided by the compatibility class from google. With this library it is possible to add sliding panels to your apps.

AHPageContainer - This object is a container for the pages of the AHViewPager. You should add Panels to this object.

AHViewPager - This is the main object which provides the sliding panels.

All the Tabs objects are deprecated now. You can use them but I don't enhance them anymore. For nice looking Tabs please use the DSTabLayout object of the DesignSupport library.
Alternatively you can use the TabStripViewPager.


Installation:
  • From V3.00 on the library requires B4A 6.0 or later.
  • This library depends on the Android Support library so you need to install the Android Support repository in the Extras section with SDK Manager.
  • Copy the AHViewPager.xml and AHViewPager.jar files to your additional libraries folder.
Example project:

For an example project for this library see the Design Support Library.

Your support:
Creating libraries and wrappers for existing library projects is a lot of work. The use of this library is totally free and you even don't need to mention in your app that you use it.
But if you use this library in your projects and you think it is useful to you please consider to make a donation:

Thanks very much for your support.

Version History:

1.00:
- initial version

1.01:
- Added AHViewPagerFixedTabs object for a fixed tab indicator
- Fixed a bug that it was impossible to get the canvas of a panel which was added to the container (It was impossible to display charts on a page)
- Example for AHViewPagerFixedTabs tab indicator

1.02: (Never released)
- Fixes problem with tab height (Line is now always on the bottom)

1.03:
- Fixes problem with Line sometimes not updating correctly on Android 4.0+
- Fix UppercaseTitle property

2.0:
- Complete Rewrite of the Swipey tabs code to fix some bugs with newer android versions.

2.01:
- New property for the AHViewPager object: PagingEnabled - Enables or disables paging for the ViewPager.

2.02:
- New events PageScrolled and PageScrollStateChanged (with SCROLLSTATE constants)
See post 227 for details

2.20:
- Use raiseEventfromUI() in most events
- New SupportTabs object
- New SupportTitles object
- Support for Designer (as a Custom View)
- some minor internal changes and bug fixes

2.21:
- Use raiseEvent() for PageCreated and PageDestroyed event again to prevent double UI refreshes
- Added @RaiseSynchronousEvents annotation to GotoPage() (to make it better compatible with rapid debugger.

3.00:
- Support for Designer Custom Properties.
- Uses maven repository to access support library. (B4A 6.0 or later required)

Attention: V2.20 has an API change which makes the ViewPager incompatible with older versions. The AHPageContainer parameter is removed from the Initialize() method. Initialize2() has the old signature. If you use Initialize() (or add the View to the Designer as a custom view) then you have to set the container object with ViewPager.PageContainer = <YourContainer>

The examples use the old Initialize method, so they are broken. I was too lazy to fix them because I recommend the tab indicator from the Design Support library for a nice looking Material Design app.
 

Attachments

  • screenshot-1336034831196.png
    screenshot-1336034831196.png
    10.1 KB · Views: 8,583
  • screenshot-1336034966953.png
    screenshot-1336034966953.png
    9.9 KB · Views: 7,840
  • AHViewPager2_21.zip
    39.8 KB · Views: 2,789
  • AHViewPager3_00.zip
    74.9 KB · Views: 2,799
Last edited:

corwin42

Expert
Licensed User
Longtime User
Can the viewpager pages be created on the fly when the number of items is not known beforehand (or is very large)?

That is possible in classic Android. An example is Gmail where you can swype through potentially thousands of emails using the viewpager. And these are not created beforehand.

Yes, it is possible with AHViewPager, too. In the example app you can dynamically add and remove pages from the menu.
 

holdemadvantage

Active Member
Licensed User
Longtime User
Hi, sorry, any tips with this kind of error? (example works, other app in which i would like to use this lib give me the error)

Parsing code. 0.28
Compiling code. 0.40

ObfuscatorMap.txt file created in Objects folder.
Compiling layouts code. 0.25
Generating R file. 0.39
Compiling generated Java code. 4.28
Convert byte code - optimized dex. Error
UNEXPECTED TOP-LEVEL EXCEPTION:
java.lang.IllegalArgumentException: already added: Landroid/support/v4/print/PrintHelper$1;
at com.android.dx.dex.file.ClassDefsSection.add(ClassDefsSection.java:122)
at com.android.dx.dex.file.DexFile.add(DexFile.java:161)
at com.android.dx.command.dexer.Main.processClass(Main.java:685)
at com.android.dx.command.dexer.Main.processFileBytes(Main.java:634)
at com.android.dx.command.dexer.Main.access$600(Main.java:78)
at com.android.dx.command.dexer.Main$1.processFileBytes(Main.java:572)
at com.android.dx.cf.direct.ClassPathOpener.processArchive(ClassPathOpener.java:284)
at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:166)
at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:144)
at com.android.dx.command.dexer.Main.processOne(Main.java:596)
at com.android.dx.command.dexer.Main.processAllFiles(Main.java:498)
at com.android.dx.command.dexer.Main.runMonoDex(Main.java:264)
at com.android.dx.command.dexer.Main.run(Main.java:230)
at com.android.dx.command.dexer.Main.main(Main.java:199)
at com.android.dx.command.Main.main(Main.java:103)
1 error; aborting
Optimized dexer failed. Switching to Standard dexer.
 

holdemadvantage

Active Member
Licensed User
Longtime User
Sure:

Admob (v. 2.00)
Anomation (V. 1.02)
Core (3.8)
Customprogressdialog (2)
DateUtils (1.05)
Dialogs (2.92)
Facebook (1.1)
HttpUtils2 (2.01)
Json
mwAdmobinterstitials2
Phone
Preferenceactivity
Randomaaccessfile
reflection
Stringfunctions
Stringutils
Ultimatelistview
XmlSax
 

gelay

Member
Licensed User
Longtime User
Hi guys

I'm trying to set the tabs over the pager layer with Pager.SendToBack or Tabs.BringToFront, but after app start "Unfortunately, xy has stopped" follows.

here is my code:

B4X:
  'Now we have a container with our panels just add it to the pager object
       Pager.Initialize(Container, "Pager")
  
       'As we want to show the tabs page indicator, we initialize it
           Tabs.Initialize(Pager)
     
           Tabs.TextSize = 18
           Tabs.LineHeight = 5dip
        Tabs.LineColorCenter = Colors.Blue  
        Tabs.TextColor = Colors.Gray
        Tabs.TextColorCenter = Colors.White
  
    Activity.AddView(Tabs, 0dip, 0dip, 100%x, 100%y)
              
              
              
       'We add a line below the tab page indicator because it looks good
    Dim Col As ColorDrawable
  
        Col.Initialize(Colors.Blue, 0)
  
       Line.Initialize("")
       Line.Background = Col
  
                     
  
       'Now we can add the pager to the activity
       Activity.AddView(Pager, 0dip, 0dip, Activity.Width, Activity.Height )
       Activity.AddView(Line, 0dip, 35dip, Activity.Width, 2dip)
       'Pager.SendToBack
       Tabs.BringToFront

Debug:

java.lang.ArithmeticException: divide by zero
at de.amberhome.viewpager.ViewPagerTabs.higlightTab(ViewPagerTabs.java:301)
at de.amberhome.viewpager.ViewPagerTabs.offsetChildren(ViewPagerTabs.java:579)
at de.amberhome.viewpager.ViewPagerTabs.onPageScrolled(ViewPagerTabs.java:559)
at android.support.v4.view.ViewPager.onPageScrolled(ViewPager.java:1717)
at android.support.v4.view.ViewPager.pageScrolled(ViewPager.java:1655)
at android.support.v4.view.ViewPager.scrollToItem(ViewPager.java:586)
at android.support.v4.view.ViewPager.onLayout(ViewPager.java:1605)
at android.view.View.layout(View.java:14858)
at android.view.ViewGroup.layout(ViewGroup.java:4646)
at anywheresoftware.b4a.BALayout.onLayout(BALayout.java:41)
at android.view.View.layout(View.java:14858)
at android.view.ViewGroup.layout(ViewGroup.java:4646)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
at android.view.View.layout(View.java:14858)
at android.view.ViewGroup.layout(ViewGroup.java:4646)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1673)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1527)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1436)
at android.view.View.layout(View.java:14858)
at android.view.ViewGroup.layout(ViewGroup.java:4646)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
at android.view.View.layout(View.java:14858)
at android.view.ViewGroup.layout(ViewGroup.java:4646)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2035)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1792)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1047)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5896)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
at android.view.Choreographer.doCallbacks(Choreographer.java:574)
at android.view.Choreographer.doFrame(Choreographer.java:544)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
to android.os.Handler.handleCallback (Handler.java:733)
to android.os.Handler.dispatchMessage (Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5105)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608)
at dalvik.system.NativeStart.main(Native Method)


Any suggestions?

Thanks
Krisztian

Somebody?
 

JakeBullet70

Well-Known Member
Licensed User
Longtime User
Hi

Is there anyway to change the text color of one of the TAB's? I looked and it seems you can change the text itself or the color of all on the init. But I cannot seem to find a way to just change 1 color. Did I miss something?

Thanks
 

corwin42

Expert
Licensed User
Longtime User
Hi, are you planning to release a B4i version of these libraries.... AHPageContainer? AHViewPager? AHViewPagerFixedTabs etc? Thanks a lot!!
No.
 

techknight

Well-Known Member
Licensed User
Longtime User
I have a weird issue with AHViewPager.

I have 4 layouts being loaded. 3 main layouts with buttons/labels/controls. and the 4th one is just a static layout with about info.

Well, it appears controls on the 3rd layout isnt getting initialized causing my program to hang. I have a timer to check if things are initialized inside an open layout before they are updated. And it keeps kicking out un-initialized. I have a seekbar on the 3rd page and it never initializes. But....

if I swipe over, the controls "initialize" and then everything is fine.

If I change my subroutine to this:
Sub Activity_Resume
If pager.IsInitialized = True Then
pager.GotoPage(1, False)
End If

gotopage 1, instead of gotopage 0, everything works fine.

any ideas how to fix this? force a layout initialization?
 
Last edited:

corwin42

Expert
Licensed User
Longtime User
Do you load all layouts in Activity_Create?

Be aware that the ViewPager only holds very few pages in memory (normally one before and after the current page). This seems to be your problem. When your activity is created only the first two pages are created by the ViewPager.
You should use the PageCreated and PageDestroyed events to add and remove your layouts from the pages. If you have a small static number of pages (like 4 as you said) you can create a global array in which you remember which pages are initialized and which not. In the PageCreated event you can then load your layouts and remember in the global array that the page is created. Then you don't have to remove the objects every time the user swipes the pages. I hope you understand what I mean.
 

techknight

Well-Known Member
Licensed User
Longtime User
Sorta ?

I do load my layouts, but...

It appears its only holding 2 pages in memory. I need at least 3 in memory at all times please....

Even though the pages arnt on the screen, there are labels, and seekbars that do get manipulated by the running program, and a config file on startup.
 
Last edited:

techknight

Well-Known Member
Licensed User
Longtime User
I basically worked around it. I modified my controls refreshing subroutine to check every single layout, and control to make sure its loaded. If not, it just simply skips it.

When when I change pages, I rerun the refresh subroutine. Kludgy, but it works.
 

techknight

Well-Known Member
Licensed User
Longtime User
Question: Can we get GPU acceleration support? I noticed on larger tablets especially with alot of stuff on the panel such as mine, it lags pretty badly.

any thoughts?
 

corwin42

Expert
Licensed User
Longtime User
Question: Can we get GPU acceleration support? I noticed on larger tablets especially with alot of stuff on the panel such as mine, it lags pretty badly.

any thoughts?

Hardware acceleration should be activated by default on newer Android versions.

You can try to add
B4X:
SetApplicationAttribute(android:hardwareAccelerated, "true")
in Manifest editor to explicitly enable it.
 

techknight

Well-Known Member
Licensed User
Longtime User
Ahh, ok, Ill give it a try. Strange it wouldnt be on by default for me.

Running kitkat cyanogenmod on my tab 2.
 

Nostrildumbass

Member
Licensed User
Longtime User
Odd, re-copying the support v4 jar fixed it, must have just gone corrupt.


Billmoultrie

Hi

I tried your example on an HTC wildfire but got the following error:

Compiling code. 0.02
Generating R file. 0.00
Compiling generated Java code. Error
B4A line: 57
container.Initialize
javac 1.6.0_23
src\de\amberhome\viewpagerexample\main.java:243: cannot access android.support.v4.view.PagerAdapter
class file for android.support.v4.view.PagerAdapter not found
mostCurrent._container.Initialize(mostCurrent.activityBA);
^
1 error
Any ideas

Thanks

I suddenly started getting this today, my app was working fine and all of a sudden I can't compile, with:

B4X:
B4A line: 66
container.Initialize
javac 1.8.0_25
src\b4a\fixme\slidingmodes.java:344: error: cannot access PagerAdapter
mostCurrent._container.Initialize(mostCurrent.activityBA);
                      ^
  class file for android.support.v4.view.PagerAdapter not found

I'm on B4A 4.0 and did place the jar and xml in my Libraries directory (I have plenty of other libraries, I'm aware of how to implement them) and I have it checked in B4A.
 
Last edited:
Top