B4A Library TabHostExtras

Here is a new library i have created that allows you to customise a TabHost.

TabHostExtras
Version: 2.2
  • TabHostExtras
    Methods:
    • GetTagWidget (TabHost1 As TabHost) As TabWidget
      Returns TabHost1's TabWidget.
      Allowing you to customize various settings.
    • getTabContentViewPadding (tabHost1 As TabHost) As RectWrapper
      Get the layout padding of tabHost1 TabContentView
      Returns a Rect object containing pixel values
    • getTabEnabled (tabHost1 As TabHost, index As Int) As Boolean
      Get the Enabled state of TabIndicator #index in tabHost1
    • getTabHeight (tabHost1 As TabHost) As Int
      Get the height (in pixels) of the TabIndicators in tabHost1
    • getTabHostPadding (tabHost1 As TabHost) As RectWrapper
      Get the layout padding of tabHost1 container View
      Returns a Rect object containing pixel values
    • getTabIcon (tabHost1 As TabHost, TabIndex As Int) As ImageViewWrapper
      Get the (icon) ImageView of TabIndicator #TabIndex in tabHost1
    • getTabTextSize (tabHost1 As TabHost) As Float
      Get the text size (in pixels) of all TabIndicators
    • getTabVisibility (tabHost1 As TabHost, index As Int) As Boolean
      Get the visibility of TabIndicators #index in tabHost1
    • setTabContentViewPadding (tabHost1 As TabHost, left As Int, top As Int, right As Int, bottom As Int)
      Set the layout padding (in dip) of tabHost1 TabContentView
    • setTabEnabled (tabHost1 As TabHost, enabled As Boolean)
      Enable or disable all TabIndicators in tabHost1
    • setTabEnabled2 (tabHost1 As TabHost, enabled As Boolean, index As Int)
      Enable or disable TabIndicator #index in tabHost1
    • setTabGradientDrawable (tabHost1 As TabHost, orientation As String, color1 As Int, color2 As Int, cornerRadius As Float)
      Set a GradientDrawable as the background on all TabIndicators in tabHost1
      All fours corner radii of the GradientDrawable are set to the value of cornerRadius (in pixels)
    • setTabGradientDrawable2 (tabHost1 As TabHost, orientation As String, color1 As Int, color2 As Int, cornerRadius() As Float)
      Set a GradientDrawable as the background on all TabIndicators in tabHost1
      Corner radii of the GradientDrawable are set individually (in pixels) based upon the number of elements in the array cornerRadius:
      1 element defines all corner radii
      2 elements define corner radii in order top left and right, bottom left and right
      4 elements define corner radii in order top-left, top-right, bottom-right, bottom-left
    • setTabHeight (tabHost1 As TabHost, tabHeight As Int)
      Set the height (in pixels) of all TabIndicators in tabHost1
    • setTabHostPadding (tabHost1 As TabHost, left As Int, top As Int, right As Int, bottom As Int)
      Set the layout padding (in dip) of tabHost1 container View
    • setTabTextColor (tabHost1 As TabHost, Color As Int)
      Set the color to be used for all tab indicators text.
      This color will be used for all tab indicators regardless of their selected state.
    • setTabTextColorStateList (tabHost1 As TabHost, ColorStateListName As String)
      Set a ColorStateList to be used for the text color of all tab indicators.
      The ColorStateList must be defined in XML in your application Objects/res/drawable folder.
      Color for selected and not selected tab state can be defined.
    • setTabTextSize (tabHost1 As TabHost, TextSize As Float)
      Set the text size of all TabIndicators
      TextSize is assumed to be in units of dip.
    • setTabTitle (tabHost1 As TabHost, Title As String, TabIndex As Int)
      Set the Title text of TabIndicator #TabIndex in tabHost1
    • setTabVisibility (tabHost1 As TabHost, visible As Boolean)
      Set the visibility of all TabIndicators in tabHost1
    • setTabVisibility2 (tabHost1 As TabHost, visible As Boolean, index As Int)
      Set the visibility of TabIndicator #index in tabHost1
  • TabWidget
    Methods:
    • BringToFront
    • GetChildTabViewAt (TabIndex As Int) As View
      Returns the tab indicator view at the given index.
      The returned View will be a ViewGroup with 2 child Views:
      An ImageView at index 0 and a TextView at Index 1.
    • GetTabIcon (TabIndex As Int) As ImageViewWrapper
      Get the (icon) ImageView of the tab indicator view at the given index.
    • GetTabLabel (TabIndex As Int) As LabelWrapper
      Get the (TextView) Label of the tab indicator view at the given index.
    • Initialize (arg1 As String)
    • Invalidate
    • Invalidate2 (arg0 As Rect)
    • Invalidate3 (arg0 As Int, arg1 As Int, arg2 As Int, arg3 As Int)
    • IsInitialized As Boolean
    • RemoveView
    • RequestFocus As Boolean
    • SendToBack
    • SetBackgroundImage (arg0 As Bitmap)
    • SetLayout (arg0 As Int, arg1 As Int, arg2 As Int, arg3 As Int)
    Properties:
    • Background As Drawable
    • Color As Int [write only]
    • DividerDrawable As Drawable [write only]
      Sets the drawable to use as a divider between the tab indicators.
    • Enabled As Boolean
      Get or Set the enabled state of the TabWidget.
    • Height As Int
    • Left As Int
    • LeftStripDrawable As Drawable [write only]
      Sets the drawable to use as the left part of the strip below the tab indicators.
    • RightStripDrawable As Drawable [write only]
      Sets the drawable to use as the right part of the strip below the tab indicators.
    • StripEnabled As Boolean
      Get or Set whether the bottom strips on the tab indicators are drawn or not.
    • TabCount As Int [read only]
      Get the number of tab indicator views.
    • Tag As Object
    • Top As Int
    • Visible As Boolean
    • Width As Int

Attached are the library files and a little demo.
If you run the demo try your device's 'Menu' key and toggle the tabs from visible to hidden.

I originally created this functionality in a code module and once it was working created the library.
So i have attached the code module as a separate attachment in case anyone wants to use it - the Reflection library is required if you use the code module but is not required if you use the library of course.

The code module has a Sub (not included in the library):

GetTabIndicators(TabHost1 As TabHost) As View()

This will return an array of Views, these Views are the TabHost's TabIndicators.
Anyone hoping to further customise the look of a TabHost may find this Sub useful - see the code module demo for an example of changing the TabIndicators' Color property.

Martin.
 

Attachments

  • TabHostExtrasCodeModule.zip
    8.9 KB · Views: 2,210
  • TabHostExtras_v2_20.zip
    22 KB · Views: 3,054
Last edited:

moster67

Expert
Licensed User
Longtime User
Thanks. Will be useful to save some space.

Sent from my HTC HD2
 

warwound

Expert
Licensed User
Longtime User
Here's is another update to TabHostExtras.

Version 1.2

Added two new methods:

1) getTabHeight(tabHost1 As TabHost) As Int

This simply returns the current height in pixels of tabHost1 tabs.

2) setTabGradientDrawable(tabHost1 As TabHost, orientation As String, color1 As Int, color2 As Int, cornerRadius As Float)

This sets a GradientDrawable as the background of all tabs in tabHost1.

See the documentation for the B4A GradientDrawable: Basic4android - Drawing (Core).

This library method accepts the same Orientation options as the B4A GradientDrawable.
"TOP_BOTTOM" and "BL_TR" for example are both valid.

color1 and color2 can be passed to the method as B4A Colors constants.
See the B4A Colors documentation: Basic4android - Constants (Core).

cornerRadius must be of type Float and defines the corner radius of the GradientDrawable.
Pass zero if you do not require rounded corners.

I've updated the demo code to set a white/blue color GradientDrawable with a "TOP_BOTTOM" orientation and no cornerRadius.

Use of this new method will require that your GradientDrawable doesn't leave the TabIndicator text unreadable either when a tab is selected or not selected.
I suspect that the default TabIndicator text color is based upon the firmware/framework of the device that your app is installed on so watch that you don't create a GradientDrawable which leaves that text unreadable on some devices.

Version 1.2 is attached to my original post in this thread.

Martin.
 

Jim Brown

Active Member
Licensed User
Longtime User
Nice little library. Is it possible to set the visiblity of individual tabs?
Or indeed the Enable/Disable state?

An extra tab index value would be needed. I was thinking something like this ...

B4X:
TabManager.setTabVisibility(TabHost1, 0,True)  ' show first tab
TabManager.setTabVisibility(TabHost1, 1,False)  ' hide second tab
...
TabManager.setTabVisibility(TabHost1, -1,State)  ' Use -1 for all tabs



TabManager.setTabEnabled(  ''''Same rules as above''' )
 

warwound

Expert
Licensed User
Longtime User
Here we go then version 1.3 of TabHostExtras...

I've added/updated the methods to set and get the visibility of either one tab or all tabs.

Existing method to set the visibility of all tabs:

setTabVisibility(tabHost1 As TabHost, visible As Boolean)
Sets the visibility of all tabs in tabHost1 to visible or hidden depending upon the value of 'visible'.

New method to set the visibility of a single tab, tabs are indexed from zero by the way:

setTabVisibility2(tabHost1 As TabHost, visible As Boolean, index As Int)
Sets the visibility of tab referenced by index in tabHost1 to visible or hidden depending upon the value of 'visible'.

Now that the visibility of individual tabs can be set, the getTabVisibility() method needed updating.

getTabVisibility(tabHost1 As TabHost, index As Int)
It now gets the visibility of a single tab, referenced by index.

Anyone currently using a version of TabHostExtras older than this new version 1.3 and using the getTabVisibility method will be required to update their code in order to use version 1.3

Sorry 'bout that but the old method is rather useless now that the visibility of individual tabs can be set.

Finally the new version has methods to set and get the Enabled state of one or all tabs in a TabHost:

setTabEnabled(tabHost1 As TabHost, enabled As Boolean)
This method will enable or disable all tabs.

setTabEnabled2(tabHost1 As TabHost, enabled As Boolean, index As int)
This method will enable or disable a single tab referenced by index.

getTabEnabled(tabHost1 As TabHost, index As int)
Gets the Enabled state of the tab referenced by index in tabHost1

Now i've updated the demo and attached all the new code to the first post in this thread.

You'll see that showing or hiding a tab messes the UI up - the tabs' bottom strip fails to redraw itself to take account of the change in the number of visible tabs.
Selecting an unselected tab will cause the UI to correctly update.

I'm looking for a java invalidate() method to call to fix this but so far have not succeeded - i'm not really sure how to reference the bottom strip and what object to call invalidate() on.

Martin.
 

warwound

Expert
Licensed User
Longtime User
Here i have another update to TabHostExtras - latest version is 1.4.

You can now set the pixel padding of the TabHost container and the TabContentView.

By default a B4A TabHost container and it's TabContentView each have padding of 5dip left, top, right and bottom.

I have created two new methods to set these padding values:

setTabHostPadding(tabHost1 As TabHost, left As int, top As int, right As int, bottom As int)
Set the layout padding (in dip) of tabHost1 container View.

setTabContentViewPadding(tabHost1 As TabHost, left As int, top As int, right As int, bottom As int)
Set the layout padding (in dip) of tabHost1 TabContentView.

I've updated the demo code to use 4dip padding top for the TabHost container and zero dip padding for the TabContentView.

Along with the option to set TabIndicator height you can reclaim even more screen space!

Version 1.4 library files and demo code are attached to the first post in this thread.

Martin.
 
D

Deleted member 103

Guest
Hello warwound,

Thanks for this library.
Can you add this feature?

wrong place to ask.
 
Last edited by a moderator:

warwound

Expert
Licensed User
Longtime User
Hello warwound,

Thanks for this library.
Can you add this feature?

B4X:
public Boolean DeleteContactById(String id)
  {
     ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
     ops.add(ContentProviderOperation.newDelete(RawContacts.CONTENT_URI)
         .withSelection(RawContacts._ID + " = ?", new String[]{id})
         .build());
      ContentResolver cr = this.m_ba.context.getContentResolver();
        try {
            cr.applyBatch(ContactsContract.AUTHORITY, ops);
        }
        catch (Exception e)
         {
           return Boolean.valueOf(false);
         }
       return Boolean.valueOf(true);
     }

Hi Filippo.

What exactly does this method do - i can't see how it's related to a TabHost?

Martin.
 
D

Deleted member 103

Guest
:signOops:

I'm sorry, the function belongs to the Contact-library. :sign0013:
 

JdV

Active Member
Licensed User
Longtime User
Controlling Roundness

Hello

Is there a way of controlling which corners of the page-tab are subjected to the rounding? In the example attached the result of rounding all 4 corners looks a little odd.

If the top corners were rounded while the bottom corners were left square that might improve the overall look.

Regards

Joe
 

Attachments

  • Screenshot.png
    Screenshot.png
    5.7 KB · Views: 1,160

warwound

Expert
Licensed User
Longtime User
Hi Joe.

Here's version 1.5 of TabHostExtras!

I've added a new method to allow you to set the individual corner radii of the GradientDrawable (in pixel units):

setTabGradientDrawable2(tabHost1 As TabHost, orientation As String, color1 As Int, color2 As Int, cornerRadius() As Float)

setTabGradientDrawable2 accepts an array of Floats as the corner radius value(s).
You can pass an array of one, two or four Floats to this new method.

Passing one Float works the same as the original setTabGradientDrawable method - all four corner radii of the GradientDrawable are set to the same value.

You can pass two Floats to set the radii of both top and both bottom corners of the GradientDrawable:

B4X:
' set a GradientDrawable as each tab indicator's background with 10 dip corner radii applied to the top left and top right of the GradientDrawable
Dim CornerRadius(2) As Float
CornerRadius(0)=10
CornerRadius(1)=0
TabManager.setTabGradientDrawable2(TabHost1, "TOP_BOTTOM", Colors.Green, Colors.Gray, CornerRadius)

And if you want to set each of the four corner radius individually then you can pass four Floats:

B4X:
' set a GradientDrawable as each tab indicator's background with different dip corner radii applied to each corner of the GradientDrawable
Dim CornerRadius(4) As Float
CornerRadius(0)=20
CornerRadius(1)=10
CornerRadius(2)=5
CornerRadius(3)=15
TabManager.setTabGradientDrawable2(TabHost1, "TOP_BOTTOM", Colors.Green, Colors.Gray, CornerRadius)

I've used pixel units for the new method, but originally intended to use dip units.
But thinking about it - the new method is more flexible if it accepts pixel units as the B4A coder can always convert the pixel units to dip units if required before calling this method.

Maybe the methods setTabContentViewPadding() and setTabHostPadding() ought to have used pixel units instead of dip units?

The new library and demo code are attached to the first post in this thread.

Martin.
 

JdV

Active Member
Licensed User
Longtime User
Thanks for the update.

Is it possible to change the colour of the line that appears below the page tabs? On my Galaxy S II it's blue - like the background of the title bar. In the emulator it's white - while the title bar background is grey. It is influenced by the colour of the title bar?

Also, in your demo where tabs can be hidden with the press of a button it doesn't seem to refresh the page tab area of the screen which can leave it looking a little odd (see screenshot attached where I have just hidden tab 2).

Regards

Joe
 

Attachments

  • screenshot 2.png
    screenshot 2.png
    9.4 KB · Views: 1,172

JonPM

Well-Known Member
Licensed User
Longtime User
I would also like to request the ability to change the color of the line below the tabs. Also, how come when I change the colors of the tabs, the black line that separates each disappears? Is there a way to adjust the width of each tab?
 

warwound

Expert
Licensed User
Longtime User
Hi JdV and JonPM.

I'll take a look at your requests when i have some spare time.
Work as always must come before play!

Martin.
 

pcbtmr

Member
Licensed User
Longtime User
Could you give an example of the use of TabContentViewPadding and TabHostPadding (or what exactly do these set?)

Thanks.
 

warwound

Expert
Licensed User
Longtime User
Hi pcbtmr.

Here the basic anatomy of a TabHost...

B4X:
<TabHost>
   <TabWidget>
      <TabIndicator />
      <TabIndicator />
   </TabWidget>

   <TabStrip />

   <TabContent />
</TabHost>

TabHost is the parent of a TabWidget, a TabStrip and a TabContent.
A TabWidget is the parent of any number of TabIndicators.

Here's a couple of screenshots and some code:

(Note that the default B4A TabHost has 5dip padding left, top, right and bottom of both the TabHost and the TabContent).

TabHost padding
B4X:
TabManager.setTabHostPadding(TabHost1, 48, 24, 48, 24)
TabManager.setTabContentViewPadding(TabHost1, 0, 0, 0, 0)
tab_host_padding.png


TabContent padding
B4X:
TabManager.setTabHostPadding(TabHost1, 0, 0, 0, 0)
TabManager.setTabContentViewPadding(TabHost1, 48, 24, 48, 24)
tab_content_padding.png


You can see that the TabWidget and the TabStrip always have a width equal to the TabHost.

Martin.
 

peacemaker

Expert
Licensed User
Longtime User
Is text size of tab heading adjustable ?
 
Top