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: 7,243
Last edited:

imgsimonebiliato

Well-Known Member
Licensed User
Longtime User
For a moment it works, but now i've got the same error:


B4X:
#Region  Activity Attributes
    #FullScreen: True
    #IncludeTitle: True
#End Region

Sub Process_Globals
End Sub

Sub Globals
Private Bar As StdActionBar
Private vp As StdViewPager
Private gTeam As CustomGridView
End Sub

Sub Activity_Create(FirstTime As Boolean)

Dim height As Int = bsValue.GetHeightSlidePanel(True, True)
vp.Initialize("vp", 3, 100%x, height)
Activity.AddView(vp.AsView, 0, 0, 100%x, 100%y - 2%y)

Bar.Initialize("bar")
Bar.Icon = LoadBitmap(File.DirAssets, "ic_action_user.png")
Bar.NavigationMode = Bar.NAVIGATION_MODE_TABS
Bar.AddTab("Partite")
Bar.AddTab("Squadra")
Bar.AddTab("Palestre")

Bar.ShowUpIndicator = True : Bar.SelectedIndex = 0
Activity.Title = bsValue.GetDesSquadra

Activity.AddMenuItem3("", "btClass"   , LoadBitmap(File.DirAssets, "classifica.png"), True)
Activity.AddMenuItem3("", "btSegnIrre", LoadBitmap(File.DirAssets, "youtube.png"), True)
Activity.AddMenuItem3("", "btFace"    , LoadBitmap(File.DirAssets, "facebook.png"), True)
end sub
 
Last edited:

imgsimonebiliato

Well-Known Member
Licensed User
Longtime User
For Android Lollip, it is normal that the button back, doesnt' work?
 

Bryan

Member
Licensed User
Longtime User
Is there a way to detect when the actionbar becomes split? I'm using the flexable table class, and I have
SetApplicationAttribute(android:uiOptions, "splitActionBarWhenNarrow") set in the manifest. The table takes up the full screen.
If the actionbar becomes split I cannot view the last row of the table. What would be a good way to work around this?

Thank you
 

Bryan

Member
Licensed User
Longtime User
Thank you, that worked perfectly.

Actually it doesn't work perfectly. I will explain...
On a 5 inch Galaxy 5 in portrait mode the action bar splits. This is where the Calculate height sub comes in handy. If the device is rotated into landscape mode and the action bar is not split any longer then I shouldn't use the Calculate height sub. Easy enough I guess to control.
When running my app on a Galaxy note 8 (8 inch tablet") in portrait mode the action bar is not split also the same goes if the Note 8 is in landscape mode. So, basically I still am unable to detect when the action bar is split to determine when I should use the Calculate height sub. The Calculate height sub only determines if you are either in portrait mode or landscape. It applies the height fix always in portrait. Larger devices won't split the action bar. I know you know all this already and I think I have seen in other posts that there is no real way to determine when the action bar is going to split. So, I ask is it better to get screen resolution and orientation and try to determine if the device is going to split the action bar? That would seem like a bit of work to get this working correctly. Any idea how the action bar itself determines whether it is going to split itself? That would seem to be the key to accurately determining available activity height. I could work around this somewhat but I can't be sure how my activity will look on other device sizes. The table I have loaded into a panel is the problem. The bottom row is not being displayed due to the action bar splitting as I mentioned in my previous post.
 

scsjc

Well-Known Member
Licensed User
Longtime User
Hello, i have a question....
can i have a repeat same layout on diferent tabs :

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

thats working perfectly, but i want know if is possible change NAME CONTROL from 1 layout ....
the idea is:

B4X:
vp.panels(0).button1.text = "hola"
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
It would have been better to start a new thread for this question.

There are all kinds of ways to organize the views references.
You can create a global button1 variable. It will hold a reference to the last view added with this name. So it allows you to do something like:
B4X:
vp.Panels(0).LoadLayout("TV")
Buttons(0) = Button1
vp.Panels(1).LoadLayout("TV")
Buttons(1) = Button1
vp.Panels(2).LoadLayout("TV")
Buttons(3) = Button1
 

Jiemde

Member
Licensed User
Longtime User
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")


Hi Erel, Is it possible to force the action bar menu items appear at the bottom in all mode ? not only in portrait mode on phone
 

klarsys

Active Member
Licensed User
Longtime User
If I want to change button Text or other properties on multiple pages, how do I do that?
I see in example that If I change button text, it reflects only in last tab.
 

samikinikar

Member
Licensed User
Longtime User
I cannot execute the given actionbar.zip code, it displays the following error
java.lang.AbstractMethodError: abstract method "void android.support.v4.view.PagerAdapter.startUpdate(android.view.View)"

It may be because of android14 or so but how to load it and from where do i get it ?

Can someone help me please ?
 

samikinikar

Member
Licensed User
Longtime User
How to check that ? I copied android-support-v4.jar into the additional library folder, but then too the same error.
 
Top