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

trueboss323

Active Member
Licensed User
Longtime User
Might be problematic. Did the ListView prevent the sliding from working properly?
Well here is the problem I have now. It seems that my list view gets cut off at the bottom of the screen. The code I have currently is:
B4X:
Dim height As Int = CalculateHeight(True, True)
Private vp As StdViewPager
    vp.Initialize("vp", 5, 100%x, height)


    Activity.AddView(vp.AsView, 0, 0, 100%x, height)

Sub CalculateHeight (TabsMode As Boolean, SplitEnabled As Boolean) As Int
   If 100%x >= 480dip Then
     Return 100%y
   Else
     Dim fix As Int
     If TabsMode Then fix = 48dip
     If SplitEnabled Then fix = fix + 48dip
     Return 100%y - fix
   End If
End Sub

I also tried replacing the height values to 100%y and tried using the AutoScale keyword in designer script, but I had no luck at all.
 

mrossen

Active Member
Licensed User
Longtime User
Hi

When I start my app I start to have 1 tab and I load 1 layout into panel(0)

B4X:
vp.Initialize("vp", 3, 100%x, height)
    Activity.AddView(vp.AsView, 0, 0, 100%x, height)
    'load the pages layouts
    vp.Panels(0).LoadLayout("0")

In tab1 I have a listview with a number of options. When I click the listview I add 2 more vp.panels and when I return to tab1 I remove the last 2 vp.panels

The problem is: When i try to slide page before I have clicked listview the code fails because I not have loaded the last 2 vp.panels.

The question is:

Should I : vp.Initialize("vp", 1, 100%x, height) at start and later change this to : vp.Initialize("vp", 3, 100%x, height) and how to do that?

or

Can I detect if a panel layout is loaded befor I try to slide the page

Mogens
 

mrossen

Active Member
Licensed User
Longtime User
Hi,

It is what I want to do.

When I then click the listview do I then have to vp.Initialize("vp", 3, 100%x, 100%y) to get 3 tabs

Do I have to to remove the activity and then do Activity.AddView(vp.AsView, 0, 0, 100%x, 100%y) Again.

I can not get this to Work properly,

Mogens
 

ttsolution

Member
Licensed User
Longtime User
Hi all,

How can I remove the bottom bar ? I want to maximize screen for another purpose

Many thanks

Jonh,
 

Taha

Member
Licensed User
Longtime User
Yesterday I upgraded my device to Android 5.0 and bar_ButtonClicked event not firing since then. Is there a workaround?
 

wildfandango

Member
Licensed User
Longtime User
Yes. Handle this event instead:
B4X:
Sub Activity_ActionBarHomeClick
  
End Sub

Thx 4 all Erel...

This Works fine for me (B4A 3.30)

Is possible change the left arrow icon showed with xx.ShowUpIndicator = True

For another picture...????

Thx in advance...
 

wildfandango

Member
Licensed User
Longtime User
Yes but in mi case, this is not a solution for 2 reasons:
  • NavigationMode=true Show a "ripple" effect on click
  • MOST IMPORTANT: NavigationMode=true works allways, the APP ico appears only under certain themes...
 

Tayfur

Well-Known Member
Licensed User
Longtime User
Hello ;

I used your sliding panels. it is very good.
I added in tabs "control list view". so, it is not sliding with tabs.

1.steps: run app
2.steps : sliding with tabs cheked . its runnig
3.steps: click button "create list" on Panel2
4.steps: sliding with tabs cheked, so list is not move.

our full sample code is attachemnt.
where is the problem.


Note : ı used costum list view links
https://www.b4x.com/android/forum/t...ew-a-flexible-list-based-on-scrollview.19567/

i used acrtionbar sliding links:
https://www.b4x.com/android/forum/threads/actionbar-sliding-pages-tutorial.36865/#post-350067

full sample project
You can download it from address: http://s000.tinyupload.com/?file_id=04389155563947391584


screenshots:

Screenshot_2015-06-29-10-03-43.png Screenshot_2015-06-29-10-05-56.png


'*************libraries****************
' contetn resolver
' CORe
' SQL
' stdActionbar
' stringutils
'*************libraries****************


B4X:
Sub Activity_Create(FirstTime As Boolean)
    If FirstTime Then
    'sh.Initialize
    cu.Initialize
    End If

    Dim height As Int = CalculateHeight(True, True)
    vp.Initialize("vp", 3, 100%x, height)
    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")
    bar.Initialize("bar")
    'bar.Icon = LoadBitmap(File.DirAssets, "giris.png")
    bar.NavigationMode = bar.NAVIGATION_MODE_TABS
    bar.AddTab("panel 0")
    bar.AddTab("panel 1")
    bar.AddTab("panel 2")
    bar.ShowUpIndicator = False' True
    bar.SelectedIndex = currentPage
    Activity.Title = "bu ana baslik"
    bar.Subtitle = "alt balikta bu"
 
    Activity.AddMenuItem3("", "mnuEdit", LoadBitmap(File.DirAssets, "ic_action_edit.png"), True)
    Activity.AddMenuItem3("", "mnuNew", LoadBitmap(File.DirAssets, "ic_action_new.png"), True)
    Activity.AddMenuItem3("", "mnuUndo", LoadBitmap(File.DirAssets, "ic_action_undo.png"), True)
    Activity.AddMenuItem3("Home", "ActionHome", LoadBitmap(File.DirAssets, "ic_action_undo.png"), True)
    Activity.AddMenuItem3("Search", "ActionSearch", LoadBitmap(File.DirAssets, "ic_action_undo.png"), True)
End Sub



...

B4X:
Sub Button1_Click
' cretae phobne list
    Rehber_yukleme
End Sub


Sub Rehber_yukleme
 
    '********************* SMS GÖNDERME VE ARAMA *****************************************
    'Dim xcall As PhoneCalls
    'Dim xsms As PhoneSms
    'xsms.Send("+905335135121","2 sistemm çalıstı")
    'Dim  sonuc As PhoneEvents
    'sonuc.Initialize("PE")
  
 
    'StartActivity( xcall.Call("02127711379"))
    '********************* SMS GÖNDERME VE ARAMA *****************************************
    'clv3.Initialize(Me, "clv3")
    clv3.Initialize(Me,"clv3")
    'clv3.Initialize(Panel_rehber,"clv3")
    'clv3.Initialize(vp.Panels(1),"clv3")
    Activity.AddView(clv3.AsView,0,Button1.Height , 100%x*0.90,100%y-Button1.Height-10)
    Dim reh_list As List
    reh_list.Initialize
    reh_list.Clear
    Dim adet As Int=cu.FindAllContacts(True).Size
    DoEvents
    Log (cu.FindAllContacts(True).Size)
    DoEvents
    Dim i As Int=0
    For Each c As cuContact In cu.FindAllContacts(True)
        reh_list.Clear
        For Each phone As cuPhone In cu.GetPhones(c.Id)
        'sb.Append(phone.Number & ", " & phone.PhoneType).Append(CRLF)
        reh_list.Add(phone.Number)
        Next
        i=i+1
        'clv3.Add(CreateListItem2( Rehber(i).isim, clv3.AsView.Width, 38dip,Rehber(i).telefon,i), 38dip, Rehber(i).id )
        DoEvents
        clv3.Add(CreateListItem2( c.DisplayName, clv3.AsView.Width, 38dip, reh_list,i ), 38dip, c.Id)
        'clv3.Add(CreateListItem2( Rehber(i).isim, clv3.AsView.Width, 38dip,Rehber(i).telefon,i), 38dip, Rehber(i).id )
    Next
 
End Sub


Sub CreateListItem2(Text As String, Width As Int, Height As Int, phonelist As List, index As Int) As Panel
    Dim p As Panel
    p.Initialize("")
    p.Color = Colors.Black
    Dim b As Button
    b.Initialize("button") 'all buttons click events will be handled with Sub Button_Click
    Dim chk As CheckBox
    chk.Initialize("chk")
    Dim lbl As Label
    lbl.Initialize("etiket")
 
    Dim spn As Spinner
    Dim spn2 As Spinner
    spn.Initialize("spn")
    spn2.Initialize("spn2")
    spn.AddAll(phonelist)
    spn2.AddAll(Array As String("< YOK >","bey","hanım"))
    lbl.Gravity = Bit.Or(Gravity.CENTER_VERTICAL, Gravity.LEFT)
    lbl.Text = Text
    lbl.TextSize = 16
    lbl.TextColor = Colors.White
    b.Text = "Click"
    chk.Tag=index
    spn2.Tag=index
    spn.Tag=index
 
    p.AddView(chk, 5dip, 2dip, 50dip, Height - 4dip) 'view #0
    p.AddView(lbl, 55dip, 2dip, 165dip, Height - 4dip) 'view #1
    p.AddView(spn, 220dip, 2dip, 170dip, Height - 4dip) 'view #2
    p.AddView(spn2, 390dip, 2dip, 150dip, Height - 4dip) 'view #3
    Return p
end sub
 
Last edited:

PABLO2013

Well-Known Member
Licensed User
Longtime User
Greetings

I using the lib with two tabs, a data base and in the other a map (osm).
How eliminate the effect of manual displacement upon touching the screen (Sliding Pages), because it interfere with the displacement of the map, I have proven with:

sub bar_TabChanged (Index Int Ace, STab StdTab Ace)
Activity.RemoveAllViews........................

but removing the views, and pass of a to another tab , make my app that is slow or lost things.

thank you

I want to know if you have some code to could help me. thank you
 

Croïd

Active Member
Licensed User
Longtime User
Nexus 10

if I created a simple menu button (activity.addmenuItem("","") , and I selects, I get this error (ANR) .

Do you have a solution ?


*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'google/mantaray/manta:5.1.1/LMY48I/2074855:user/release-keys'
Revision: '8'
ABI: 'arm'
pid: 28343, tid: 28343, name: emple.b4a.maps >>> com.exemple.b4a.maps <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xc
r0 00000000 r1 b915a7a0 r2 00000000 r3 00000000
r4 b915a7a0 r5 00000000 r6 00000000 r7 b915b0c0
r8 bec300a0 r9 b915b07c sl 0000001d fp 00000001
ip b681ae94 sp bec30030 lr b6813837 pc b6812ad4 cpsr 600f0030

backtrace:
#00 pc 00011ad4 /system/lib/libinput.so (android::InputChannel::receiveMessage(android::InputMessage*)+11)
#01 pc 00012833 /system/lib/libinput.so (android::InputConsumer::consume(android::InputEventFactoryInterface*, bool, long long, unsigned int*, android::InputEvent**)+58)
#02 pc 0007930d /system/lib/libandroid_runtime.so (android::NativeInputEventReceiver::consumeEvents(_JNIEnv*, bool, long long, bool*)+84)
#03 pc 00079503 /system/lib/libandroid_runtime.so (android::NativeInputEventReceiver::handleEvent(int, int, void*)+46)
#04 pc 00012545 /system/lib/libutils.so (android::Looper:eek:llInner(int)+484)
#05 pc 000125ed /system/lib/libutils.so (android::Looper:eek:llOnce(int, int*, int*, void**)+92)
#06 pc 00081709 /system/lib/libandroid_runtime.so (android::NativeMessageQueue:eek:llOnce(_JNIEnv*, int)+22)
#07 pc 000b3863 /data/dalvik-cache/arm/system@[email protected]
 

imgsimonebiliato

Well-Known Member
Licensed User
Longtime User
Hello,
when I initialize the properties ".icon" and ".NavigationMode",
I've got these errors:


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


java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.ActionBar.setNavigationMode(int)' on a null object reference

How to fix?
 
Top