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,076
  • TabHostExtras_v2_20.zip
    22 KB · Views: 2,912
Last edited:

canalrun

Well-Known Member
Licensed User
Longtime User
Hello,

I am using TabHostExtras in B4A 3.5 to update an app created with an earlier version of B4A. I only use four functions of TabHostExtras; setTabHeight, setTabTextSize, setTabTextColor, and setTabTextColorStateList. I haven't noticed any problems.

Barry.
 

warwound

Expert
Licensed User
Longtime User
Hello,

I am using TabHostExtras in B4A 3.5 to update an app created with an earlier version of B4A. I only use four functions of TabHostExtras; setTabHeight, setTabTextSize, setTabTextColor, and setTabTextColorStateList. I haven't noticed any problems.

Barry.

But if you download and run the demo project in post #1 of this thread does it work as expected?
I see nothing on the Activity - no TabHost etc.

Martin.
 

canalrun

Well-Known Member
Licensed User
Longtime User
I downloaded and tried the post #1 demo, TabHostExtrasDemo, and I think I got the same results as you. With B4A version 3.5 the demo shows a blank screen. I re-downloaded the demo code and tried with B4A version 3.0 (it's still on my computer). The demo shows some tabs and the UK Google webpage.

Below are some screenshots of the two tries:

B4A version 3.0:

upload_2014-3-22_14-10-56.png



B4A version 3.5:

upload_2014-3-22_14-11-36.png


I don't have B4A version 3.2 installed. That may be an interesting test.

Barry.
 

Attachments

  • upload_2014-3-22_14-7-49.png
    upload_2014-3-22_14-7-49.png
    43.2 KB · Views: 220

iCAB

Well-Known Member
Licensed User
Longtime User
Can you please show a code example. I can't seem to find the property to set
Thanks
 

canalrun

Well-Known Member
Licensed User
Longtime User
As more of an exercise, I modified warwound's post #1 demo attempting what Erel suggested. Using B4A 3.5 I went into the designer and noticed that each layout included views with height and/or width parameters of -1. I changed these to values in the neighborhood of 50 or 300. In the code main module I did a Tabost1.SetLayout(...) to make it full screen.

Here is what I get when running:

upload_2014-3-26_1-11-47.png


I have attached the project zip export.

What I didn't do, and have no experience doing, is using the anchors feature to fill the screen as Erel suggested. That would probably be a better way of achieving what I did.

If somebody could describe that procedure (in a few sentences) and maybe modify my uploaded export, that would be very helpful to everyone.

Barry.
 

Attachments

  • TabHostExMod.zip
    9.7 KB · Views: 233

iCAB

Well-Known Member
Licensed User
Longtime User
I use the layout in the layout file in the POST #1, and everything works great.

Thanks
 

warwound

Expert
Licensed User
Longtime User
Hi, there are some way to customize the tab headers color individually?

I think that's possible but requires an update to the library.
Is there an existing TabHostExtras method which updates all TabIndicators which you'd like to use to instead update a single TabIndicator?
For example do you want to use a method such as setTabTextColor or setTabGradientDrawable that you want to use to change a single TabIndicator instead of all TabIndicators?

Give me a bit more detail about what you require and i should be able to update the library.
(Do you want to set text or background color?).

Martin.
 

warwound

Expert
Licensed User
Longtime User
@sotik

Here's an updated TabHostExtras for you to try.
I've created a new TabHostExtras method:

GetTagWidget (TabHost1 As TabHost) As TabWidget
Returns TabHost1's TabWidget.
Allowing you to customize various settings.


The reference for the android TabWidget can be found here:
http://developer.android.com/reference/android/widget/TabWidget.html

The TabWidget contains a TabIndicator for each 'content' Tab in the TabHost.
Each TabIndicator is an icon and a label.

This is the reference for my b4a TabWidget:

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

So you can get the various components of the TabWidget and customise as desired - without me having to write endless getter and setter methods for each and every possibility!

That's the theory.
In practice there is one problem...
A TabWidget is meant to be created when the TabHost is created.
If you modify a TabWidget after the TabHost has been created - as this library does - then some modifications may not be reflected in the TabHost.
That is you might change a property but see no change on the device screen.
I see a possible fix for this in the android documentation if anyone experiences this problem i will try the fix.

So to answer your question - you'd get whichever TabIndicator Label you wish to customise and use the various b4a Label methods and properties to change it's appearance.

Can you post again and let me know how well this update works?
If it works as expected i'll make it into a 'proper' update and update post #1.

Thanks.

Martin.
 

sotik

Member
Licensed User
Longtime User
@sotik

Here's an updated TabHostExtras for you to try.
I've created a new TabHostExtras method:

GetTagWidget (TabHost1 As TabHost) As TabWidget
Returns TabHost1's TabWidget.
Allowing you to customize various settings.


The reference for the android TabWidget can be found here:
http://developer.android.com/reference/android/widget/TabWidget.html

The TabWidget contains a TabIndicator for each 'content' Tab in the TabHost.
Each TabIndicator is an icon and a label.

This is the reference for my b4a TabWidget:

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

So you can get the various components of the TabWidget and customise as desired - without me having to write endless getter and setter methods for each and every possibility!

That's the theory.
In practice there is one problem...
A TabWidget is meant to be created when the TabHost is created.
If you modify a TabWidget after the TabHost has been created - as this library does - then some modifications may not be reflected in the TabHost.
That is you might change a property but see no change on the device screen.
I see a possible fix for this in the android documentation if anyone experiences this problem i will try the fix.

So to answer your question - you'd get whichever TabIndicator Label you wish to customise and use the various b4a Label methods and properties to change it's appearance.

Can you post again and let me know how well this update works?
If it works as expected i'll make it into a 'proper' update and update post #1.

Thanks.

Martin.



Hi mate, i got a problem with this.

When i do this:

dim ext as TabHostExtras
Dim lbl As Label
lbl.Initialize("lbl")
lbl = ext.GetTagWidget(Tb).GetTabLabel(0)

I get an error: java.lang.ClassCastException: android.widget.ImageView cannot be cast to android.widget.TextView
 

Robert Valentino

Well-Known Member
Licensed User
Longtime User
When I used TabHostExtras with my manifest set to
B4X:
<uses-sdk android:minSdkVersion="4"/>
to see how it looks on older systems


The Tab Text Title appears at the bottom of the tab instead of center vertically if fact it is so low in the tab the bottoms of the letter y get chopped off.

Is anyone else having this problem? Is there a fix for this?

Thanks

BobVal
 

sotik

Member
Licensed User
Longtime User
hi,
What happens when there are many tabs, for example 9 or 10, the title of each one is too difficult to see. there any way to paginate this?, ie, there is a slider or something to see a certain number of tabs at once?
 

RjCl

Member
Licensed User
Longtime User
Hello Martin,

Could you give an example of changing the Tab colors for selected and not selected using the TabWidget in your library? Like this?

B4X:
TabManager.GetTagWidget(TabHost1).Color = Colors.Magenta

Couldn't get it to work, its just changed the color of Strip.
 

warwound

Expert
Licensed User
Longtime User
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.

The TabWidget is a View that contains TabIndicators, your code has set the Color property of the TabWidget whereas you want to set the Color property of each TabIndicator?

I think you can do that with the method:

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.

The ColorStateList defines the color of each TabIndicator depending on whether it's selected or not selected.
There's some more info here: http://www.b4x.com/android/forum/threads/tabhostextras.11056/page-3#post-109232.

Martin.
 
Top