[B4X] PillDotsIndicator — Page Indicator with MORPH & SLIDE styles (B4A/B4i/B4J)
PillDotsIndicator is a lightweight, cross-platform B4X custom view for showing page indicators.
It comes with two animation styles:
- MORPH: The active dot morphs into a pill shape with smooth width and color transition.
- SLIDE: A circular cursor smoothly slides between dots.
It’s perfect for onboarding screens, ViewPager indicators, or any kind of paginated content.
Features
- 100% B4X code (works in B4A / B4i / B4J)
- Two animation styles: MORPH and SLIDE
- Designer Properties support
- Event: PageChanged (Index As Int)
- Easy methods: SetProgress, NextPage, PrevPage, etc.
- Runtime color customization
Designer Properties
- PageCount (Int) — number of pages (default: 4)
- DotSize (dip) — size of dots (default: 12dip)
- ActiveWidth (dip) — active pill width in MORPH style (default: 32dip)
- Spacing (dip) — spacing between dots (default: 10dip)
- ActiveColor (Color) — active dot color (default: 0xFF3A82F7)
- InactiveColor (Color) — inactive dot color (default: 0xFF3A82F7)
- BgColor (Color) — background color of the view (default: transparent)
- Duration (ms) — animation duration (default: 220ms)
- StartIndex (Int) — start index (default: 0)
- Style (String) — MORPH or SLIDE (default: MORPH)
Event
Event:
#Event: PageChanged (Index As Int)
Public Methods
publicmethods:
Public Sub setPageCount(n As Int)
Public Sub getPageCount As Int
Public Sub getCurrentIndex As Int
Public Sub SetCurrentIndex(i As Int) ' animated
Public Sub SetProgress(index As Int) ' same as SetCurrentIndex
Public Sub NextPage
Public Sub PrevPage
Public Sub SetColors(Active As Int, Inactive As Int)
Quick Start
1) Add it in Designer
- Add PillDotsIndicator.bas class to your project.
- In Designer, drop a CustomView and set its type to PillDotsIndicator.
- Configure properties (PageCount, Style, etc).
- Give it a name (e.g. ind).
Works in B4A, B4i, and B4J.
Sample — B4XPages + B4XViewPager
Globals
Globals:
Sub Class_Globals
Private Root As B4XView
Private xui As XUI
Private vp As B4XViewPager
Private ind As PillDotsIndicator ' CustomView from Designer
End Sub
B4XPage_Created
B4xPageCreate:
Private Sub B4XPage_Created (Root1 As B4XView)
Root = Root1
Root.LoadLayout("MainPage") ' contains vp and ind
vp.Initialize
For i = 0 To 4
Dim p As B4XView = xui.CreatePanel("")
p.Color = 0xFFEFEFEF
vp.AddPage(p, "Page " & i)
Next
ind.setPageCount(vp.PageCount)
End Sub
Sync ViewPager → Indicator
SyncViewPager:
Private Sub vp_PageChanged (Position As Int)
ind.SetProgress(Position)
End Sub
Sync Indicator → ViewPager
SyncIndicator:
Private Sub btnNext_Click
ind.NextPage
vp.GotoPage(ind.getCurrentIndex, True)
End Sub
Private Sub btnPrev_Click
ind.PrevPage
vp.GotoPage(ind.getCurrentIndex, True)
End Sub
Simple Example (no ViewPager)
NoViewPager:
Private Sub B4XPage_Appear
StartTimer
End Sub
Private Sub StartTimer
Dim t As Timer
t.Initialize("t", 1500)
t.Enabled = True
End Sub
Private Sub t_Tick
If ind.getCurrentIndex < ind.getPageCount - 1 Then
ind.NextPage
Else
ind.SetCurrentIndex(0)
End If
End Sub
Change Colors at Runtime
ChangeColor:
ind.SetColors(0xFF000000, 0xFFBDBDBD) ' Active=Black, Inactive=Gray
Tips
- For MORPH, set ActiveWidth larger than DotSize (e.g. DotSize=12, ActiveWidth=36) for a nicer morph effect.
- Increase Duration (e.g. 260–300ms) if the animation feels too fast.
- The class auto-centers the dots inside its base view. Just anchor/center the CustomView in your layout.
Version History
- v1.0.0: Initial release with MORPH + SLIDE styles, designer properties, PageChanged event, and core methods.
License
ELCIDCredit/link back to this thread is appreciated

Files
- PillDotsIndicator.bas (the custom view)
- Sample Project (B4XPages + B4XViewPager example)
