Android Tutorial ActionBar / Sliding Pages tutorial

A simpler and better looking solution is now available: https://www.b4x.com/android/forum/threads/tabstripviewpager-better-viewpager.63975/

StdActionBar library allows you to create layouts that use the action bar as a navigation interface.
Note that StdActionBar requires Android 4+.

In this tutorial we will create this layout:

upload_2014-1-19_15-27-46.png
upload_2014-1-19_15-28-3.png


The user can switch pages with a swipe gesture.

StdViewPager holds several panels and supports the swipe gesture.

Using StdViewPager is quite simple:

1. Initialize it and set the number of pages and their size.
2. Add it to its parent.
3. Create the internal pages layouts.

B4X:
Dim height As Int = CalculateHeight(True, True)
vp.Initialize("vp", 3, 100%x, height) 'vp is a StdViewPager object
Activity.AddView(vp.AsView, 0, 0, 100%x, height)
'load the pages layouts
vp.Panels(0).LoadLayout("0")
vp.Panels(1).LoadLayout("1")
vp.Panels(2).LoadLayout("2")

The next step is to add the ActionBar tabs:
B4X:
bar.Initialize("bar")
bar.NavigationMode = bar.NAVIGATION_MODE_TABS
bar.AddTab("Tab 1")
bar.AddTab("Tab 2")
bar.AddTab("Tab 3")

We need to synchronize the selected tab and the selected page:
B4X:
Sub VP_PageSelected (Position As Int)
   If bar.SelectedIndex <> Position Then bar.SelectedIndex = Position
End Sub

Sub bar_TabChanged(Index As Int, STab As StdTab)
   If vp.currentPage <> Index Then vp.ScrollTo(Index, False)
End Sub

CalculateHeight (TabsMode As Boolean, SplitEnabled As Boolean) is a helper sub that calculates the pages height based on the two features.
As you can see in the first screenshot, the split mode is enabled in this case. In split mode the action bar menu items appear at the bottom in portrait mode (phones only). This is set by adding the following line to the manifest editor:
B4X:
SetApplicationAttribute(android:uiOptions, "splitActionBarWhenNarrow")

The project is attached. Note that it requires StdActionBar v1.50+.

Tips:

- You can show the "up indicator" by setting ShowUpIndicator to True:

SS-2014-01-19_15.41.50.png


You can then handle the ButtonClicked event and use it to navigate to the "parent" activity.

- The holo.light theme is used in this project. It is done with this manifest line:
B4X:
SetApplicationAttribute(android:theme, "@android:style/Theme.Holo.Light")
 

Attachments

  • ActionBar.zip
    14.1 KB · Views: 6,806
Last edited:

samikinikar

Member
Licensed User
The output is as follows...

Setting install_non_market_apps has moved from android.provider.Settings.Global to android.provider.Settings.Secure, returning read-only value.
Timeline: Activity_idle id: android.os.BinderProxy@26506abd time:102233599
Timeline: Activity_launch_request id:b4a.example time:102276689
** Activity (main) Pause, UserClosed = false **
** Service (starter) Create **
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
22
** Activity (main) Resume **
 

samikinikar

Member
Licensed User
I am using 5.5 trial version, I have not changed a single line of code, directly executing the given example, the final output after running the program is as follows.

** Activity (main) Pause, UserClosed = false **
** Activity (main) Create, isFirst = true **
Error occurred on line: 36 (Main)
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.ActionBar.setIcon(android.graphics.drawable.Drawable)' on a null object reference
at anywheresoftware.b4a.objects.StdActionBar.setIcon(StdActionBar.java:227)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at anywheresoftware.b4a.shell.Shell.runVoidMethod(Shell.java:742)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:342)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:246)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:134)
at b4a.example.test123.main.afterFirstLayout(main.java:102)
at b4a.example.test123.main.access$000(main.java:17)
at b4a.example.test123.main$WaitForLayout.run(main.java:80)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5292)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
** Activity (main) Resume **
** Activity (main) Resume **
 

u2005k

Member
Licensed User
Hi
Netchicken,

I've made a solution with one Activity and classes loading Layouts and this works fine for me so far. Supplied here are the framework of this setup. I've been searching a lot for a working solution and thought I'd share this, might help others in the same situation.

The Activity has an Actionbar in top and another in bottom (which works as a statusbar for me).
Changes in the Actionbars can be done by calling a sub in Main like:
B4X:
CallSub(Main,"ActivityLowerBar")
or in the top bar
B4X:
CallSub(Main,"ActivityTopBar")
I use KeyValueStore to send variables between classes and activity, a bit slower than global variables but safer if the app shuts down.

I also have slidingmenues (http://www.basic4ppc.com/android/forum/threads/jfeinstein10-slidingmenu-library.36482/) to the left, with buttons for selecting function and to the right with a ScrollView that can be used for anything you want.

The menubuttons loads the classes like this:
B4X:
sm.HideMenus
Activity.RemoveAllViews
lClsHistory.Initialize(Me, Activity, 2)
Then the class loads the Layouts and each class will handle the events from that layout.
This means you have the Activity common for the project and just change the visible layouts by initializing the classes.

I've also implemented a Multilanguage function based on this http://www.basic4ppc.com/android/forum/threads/ahlocale-library.7561/.
Texts are used in this way:
B4X:
btnKund.text=trans.GetText("Customer")
I only have Swedish at the moment as complement to English (the english is the text Customer above) and the Swedish is looked up in a text file in the folder /Files.

Noticed that the Backbutton on the device don't work but thats easy to solve for you...
The sliding doesn't work so good on the emulator but it does on a real device.

Notice that you will need some libraries...
Since this frame is taken from my complete app there are a lot of libs and I really don't know which are used for only the frame to work... But try and add them one at a time when you get error...
These are the libs used: AHLocale, Core, DateUtils, Dialogs, HTTP, JavaObject, JSON, Net, Phone, RandomAccessFile, Reflection, ScrollView2D, SlidingMenuWrapper, SQL, StdActionbar, StringFunctions, StringUtils, TabHostExtras, XmlSax.

Hi Roger,
I get error resource directory 'c:\androidapps\dagbokvit\slidingmenu\library\res' does not exist. Where do I get these resources?
Thanks
U2005K
 

cxdzbl

Active Member
Licensed User
A simpler and better looking solution is now available: https://www.b4x.com/android/forum/threads/tabstripviewpager-better-viewpager.63975/

StdActionBar library allows you to create layouts that use the action bar as a navigation interface.
Note that StdActionBar requires Android 4+.

In this tutorial we will create this layout:

View attachment 22073 View attachment 22074

The user can switch pages with a swipe gesture.

StdViewPager holds several panels and supports the swipe gesture.

Using StdViewPager is quite simple:

1. Initialize it and set the number of pages and their size.
2. Add it to its parent.
3. Create the internal pages layouts.

B4X:
Dim height As Int = CalculateHeight(True, True)
vp.Initialize("vp", 3, 100%x, height) 'vp is a StdViewPager object
Activity.AddView(vp.AsView, 0, 0, 100%x, height)
'load the pages layouts
vp.Panels(0).LoadLayout("0")
vp.Panels(1).LoadLayout("1")
vp.Panels(2).LoadLayout("2")

The next step is to add the ActionBar tabs:
B4X:
bar.Initialize("bar")
bar.NavigationMode = bar.NAVIGATION_MODE_TABS
bar.AddTab("Tab 1")
bar.AddTab("Tab 2")
bar.AddTab("Tab 3")

We need to synchronize the selected tab and the selected page:
B4X:
Sub VP_PageSelected (Position As Int)
   If bar.SelectedIndex <> Position Then bar.SelectedIndex = Position
End Sub

Sub bar_TabChanged(Index As Int, STab As StdTab)
   If vp.currentPage <> Index Then vp.ScrollTo(Index, False)
End Sub

CalculateHeight (TabsMode As Boolean, SplitEnabled As Boolean) is a helper sub that calculates the pages height based on the two features.
As you can see in the first screenshot, the split mode is enabled in this case. In split mode the action bar menu items appear at the bottom in portrait mode (phones only). This is set by adding the following line to the manifest editor:
B4X:
SetApplicationAttribute(android:uiOptions, "splitActionBarWhenNarrow")

The project is attached. Note that it requires StdActionBar v1.50+.

Tips:

- You can show the "up indicator" by setting ShowUpIndicator to True:

SS-2014-01-19_15.41.50.png


You can then handle the ButtonClicked event and use it to navigate to the "parent" activity.

- The holo.light theme is used in this project. It is done with this manifest line:
B4X:
SetApplicationAttribute(android:theme, "@android:style/Theme.Holo.Light")

At the time of using this library. Every time the software starts to go through a default interface with the software name, a flash before entering the Activity.LoadLayout ("layout"). How can we directly access the layout main
 

cxdzbl

Active Member
Licensed User
I recommend you to switch to TabStripViewPager. I tested it in release mode. The layout appears very quickly. There is a very short moment where you see an empty activity.


1, when you directly from the first page to click on the third page of the total to go through second pages, this is not as good as stdveiwpager.
2, at the start of the same time there is a short blank interface.
 

u2005k

Member
Licensed User
A simpler and better looking solution is now available: https://www.b4x.com/android/forum/threads/tabstripviewpager-better-viewpager.63975/

StdActionBar library allows you to create layouts that use the action bar as a navigation interface.
Note that StdActionBar requires Android 4+.

In this tutorial we will create this layout:

View attachment 22073 View attachment 22074

The user can switch pages with a swipe gesture.

StdViewPager holds several panels and supports the swipe gesture.

Using StdViewPager is quite simple:

1. Initialize it and set the number of pages and their size.
2. Add it to its parent.
3. Create the internal pages layouts.

B4X:
Dim height As Int = CalculateHeight(True, True)
vp.Initialize("vp", 3, 100%x, height) 'vp is a StdViewPager object
Activity.AddView(vp.AsView, 0, 0, 100%x, height)
'load the pages layouts
vp.Panels(0).LoadLayout("0")
vp.Panels(1).LoadLayout("1")
vp.Panels(2).LoadLayout("2")

The next step is to add the ActionBar tabs:
B4X:
bar.Initialize("bar")
bar.NavigationMode = bar.NAVIGATION_MODE_TABS
bar.AddTab("Tab 1")
bar.AddTab("Tab 2")
bar.AddTab("Tab 3")

We need to synchronize the selected tab and the selected page:
B4X:
Sub VP_PageSelected (Position As Int)
   If bar.SelectedIndex <> Position Then bar.SelectedIndex = Position
End Sub

Sub bar_TabChanged(Index As Int, STab As StdTab)
   If vp.currentPage <> Index Then vp.ScrollTo(Index, False)
End Sub

CalculateHeight (TabsMode As Boolean, SplitEnabled As Boolean) is a helper sub that calculates the pages height based on the two features.
As you can see in the first screenshot, the split mode is enabled in this case. In split mode the action bar menu items appear at the bottom in portrait mode (phones only). This is set by adding the following line to the manifest editor:
B4X:
SetApplicationAttribute(android:uiOptions, "splitActionBarWhenNarrow")

The project is attached. Note that it requires StdActionBar v1.50+.

Tips:

- You can show the "up indicator" by setting ShowUpIndicator to True:

SS-2014-01-19_15.41.50.png


You can then handle the ButtonClicked event and use it to navigate to the "parent" activity.

- The holo.light theme is used in this project. It is done with this manifest line:
B4X:
SetApplicationAttribute(android:theme, "@android:style/Theme.Holo.Light")

Is it possible to get click event on icon on standard action bar? Using ShowUpIndicator does not very well go with theme that we are using.

Thanks & regards...
U2005K
 

victormedranop

Well-Known Member
Licensed User
HI, in the example I have this sentence
B4X:
Activity.AddMenuItem3("", "mnuUndo", LoadBitmap(File.DirAssets, "exit.png"), True)

but I try with an event to change the image but I cant find the way to modify the menuitem when its running

thanks

Victor
 

Drago Bratko

Member
Licensed User
I have same problem as in post number #79 in this thread.
I see that in post #84 it was handled. Can you share solution ?
In my case it's broken on this line : bar.Icon = LoadBitmap(File.DirAssets, "ic_action_user.png")

B4X:
    'load the pages layouts
    vp.Panels(0).LoadLayout("ProizvodiTop")
    vp.Panels(1).LoadLayout("Postavke")
    vp.Panels(2).LoadLayout("Login")
    bar.Initialize("bar")
    bar.Icon = LoadBitmap(File.DirAssets, "ic_action_user.png")
    bar.NavigationMode = bar.NAVIGATION_MODE_TABS
    bar.AddTab("Top proizvodi")
    bar.AddTab("Proizvodi a-z")
    bar.AddTab("Račun")
    bar.ShowUpIndicator = True
    bar.SelectedIndex = currentPage

Error is :
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.ActionBar.setIcon(android.graphics.drawable.Drawable)' on a null object reference

This is code from example copied to my project. In folder "Files" there us image "ic_action_user.png".
SDK version which I got it with : Log(p.SdkVersion) is 24.
 
Last edited:
Top