B4A Library TabHostExtras

RjCl

Member
Licensed User
Longtime User

No, sorry, not the text of whats written on the tabs, i managed to do that from your previous example a few pages back and is working great.
I'm wanting to change the actual color of the tab not the text on the tab ?
 

warwound

Expert
Licensed User
Longtime User
Ah yes that'll only modify the tab indicator text color not background color.

I've modified the TabHost tutorial example:

B4X:
Sub Activity_Create(FirstTime As Boolean)
	Activity.LoadLayout("main")
	Dim bmp1, bmp2 As Bitmap
	bmp1 = LoadBitmap(File.DirAssets, "ic.png")
	bmp2 = LoadBitmap(File.DirAssets, "ic_selected.png")
	
	TabHost1.AddTabWithIcon ("Name", bmp1, bmp2, "page1") 'load the layout file of each page
	TabHost1.AddTab("Color", "page2") 
	TabHost1.AddTab("Animal", "page3")
	
	Dim ColorDrawable1 As ColorDrawable
	ColorDrawable1.Initialize(Colors.Blue, 0)
	
	Dim ColorDrawable2 As ColorDrawable
	ColorDrawable2.Initialize(Colors.Red, 0)
	
	Dim StateListDrawable1 As StateListDrawable
	StateListDrawable1.Initialize
	StateListDrawable1.AddState(StateListDrawable1.State_Selected, ColorDrawable1)
	StateListDrawable1.AddCatchAllState(ColorDrawable2)
	
	Dim TabHostExtras1 As TabHostExtras
	Dim TabIndicator As Panel=TabHostExtras1.GetTagWidget(TabHost1).GetChildTabViewAt(0)
	TabIndicator.Background=StateListDrawable1
End Sub

The TabWidget GetChildTabViewAt method returns an android ViewGroup type of object which can be assigned to a b4a Panel.
Now we can set the Panel Background property to a Drawable.
I've used a StateListDrawable which will appear red when selected and blue at all other times.

The example works BUT i see a problem on my Moto G (kitkat).
When the Panel Background is initially set it overflows the area which it originally occupied.
Click any other tab and the TabHost redraws itself and the Panel background appears as expected.

So try this.
Create a Drawable for the 'selected' state and a Drawable for the 'not selected' state then create a StateListDrawable from these two Drawables.
Now iterate through the tab indicators, setting their Background property to the StateListDrawable.

Martin.
 

Attachments

  • tabindicator-background.zip
    11.1 KB · Views: 227

RjCl

Member
Licensed User
Longtime User

Thank you so much! It working alright so far

Just one other thing, if you could help me..........How to choose another color by say hex value ? Is it ColorDrawable1.Initialize(#2F4F4F, 0) ?
 

warwound

Expert
Licensed User
Longtime User
No, it didn't work....Logging DecimalInteger was 3100495 ?

That may well be a valid integer for a color value - try setting it and see what you get.
Remember that color hex values range from 0 to FFFFFFFF so a large integer value isn't necessarily incorrect.

Martin.
 

RjCl

Member
Licensed User
Longtime User
That may well be a valid integer for a color value - try setting it and see what you get.
Remember that color hex values range from 0 to FFFFFFFF so a large integer value isn't necessarily incorrect.

Martin.

It comes up blank, not showing the color its supposed to
 

warwound

Expert
Licensed User
Longtime User
http://stackoverflow.com/questions/6935057/convert-hex-color-value-ffffff-to-integer-value

Simply parsing an HTML hex color code to an integer won't work for android's color property.
This is a long winded approach but does work:

B4X:
Sub Activity_Create(FirstTime As Boolean)
	Activity.LoadLayout("main")
	Dim bmp1, bmp2 As Bitmap
	bmp1 = LoadBitmap(File.DirAssets, "ic.png")
	bmp2 = LoadBitmap(File.DirAssets, "ic_selected.png")
	
	TabHost1.AddTabWithIcon ("Name", bmp1, bmp2, "page1") 'load the layout file of each page
	TabHost1.AddTab("Color", "page2") 
	TabHost1.AddTab("Animal", "page3")
	
	Dim ColorDrawable1 As ColorDrawable
	'	parse the HTML hex color code as red, green and blue elements
	ColorDrawable1.Initialize(Colors.RGB(Bit.ParseInt("2f", 16), Bit.ParseInt("4f", 16), Bit.ParseInt("4f", 16)), 0)
	
	Dim ColorDrawable2 As ColorDrawable
	ColorDrawable2.Initialize(Colors.Magenta, 0)
	
	Dim StateListDrawable1 As StateListDrawable
	StateListDrawable1.Initialize
	StateListDrawable1.AddState(StateListDrawable1.State_Selected, ColorDrawable1)
	StateListDrawable1.AddCatchAllState(ColorDrawable2)
	
	Dim TabHostExtras1 As TabHostExtras
	Dim TabIndicator As Panel=TabHostExtras1.GetTagWidget(TabHost1).GetChildTabViewAt(0)
	TabIndicator.Background=StateListDrawable1
End Sub

Martin.
 

RjCl

Member
Licensed User
Longtime User

Thank you
 

RjCl

Member
Licensed User
Longtime User
Hello Martin,

Is there a setting for the tab text position ? Currently letters like g, y are getting cut off from the bottom.....There seems to be more space above the text than below.

Also, I can't get the dividers showing back between the tabs like in your demo.
 

warwound

Expert
Licensed User
Longtime User
May I ask how I can just remove the outer padding of the tabhost, using reflection?

Here's the source code for the setTabHostPadding method:

B4X:
/**
 * Set the layout padding (in dip) of tabHost1 container View
 */
public static void setTabHostPadding(TabHost tabHost1, int left, int top, int right, int bottom){
	tabHost1.getChildAt(0).setPadding(Common.DipToCurrent(left), Common.DipToCurrent(top), Common.DipToCurrent(right), Common.DipToCurrent(bottom));
}

Martin.
 

RjCl

Member
Licensed User
Longtime User

Martin,

Any ideas about why the text is positioned as it is?
 

warwound

Expert
Licensed User
Longtime User
Martin,

Any ideas about why the text is positioned as it is?

Not really

If i had this problem i'd probably start my app, then open the folder containing the android sdk and run the Hierarchy Viewer.
The Hierarchy Viewer shows a tree based view and you can navigate to whichever view you want to inspect.

I'd navigate to the TextView (Label) that is a tab indicator and look at it's properties.
See if a padding or margin property has been set and this is not leaving enough space for the text to properly display.
Look at other properties too - once you find the cause i can look at some code to fix the problem.

Martin.
 

RjCl

Member
Licensed User
Longtime User

How do you mean start app? On the device while running B4A ?
 

warwound

Expert
Licensed User
Longtime User
Run your b4a project so your device is running your project and is connected to your computer via USB.
Now you should be able to run the Hierarchy Viewer, select your device and select your running project by identifying it's packagename in the list of running packages.
Finally you get a graphical tree showing all Views currently displayed in your app and should be able to navigate to the TextView which is the tab indicator displaying your squashed text.

Martin.
 

RjCl

Member
Licensed User
Longtime User
I tried as you said, connected USB, its in debug mode, run in debug and started app and then hierarchy viewer but i get the following errors:-

B4X:
05:26:46 E/hierarchyviewer: Missing forwarded port for 42583930325834465A58
05:26:46 E/hierarchyviewer: Unable to load window data for window <Focused Windo
w> on device 42583930325834465A58
05:26:46 E/hierarchyviewer: null

Hierarchy Viewer is showing device but nothing else when clicking, just get that error in command prompt
 

Controller

Member
Licensed User
Longtime User
B4X:
Sub TabHost_SetTabPadding(xTabHost As TabHost, Left As Int, Top As Int, Right As Int, Bottom As Int)
    Dim xRef1 As Reflector
    Dim xRef2 As Reflector
    Dim xInt1 As Int
    Dim xInt2 As Int
   
    xRef1.Target = xTabHost
    xRef1.Target = xRef1.RunMethod("getTabWidget")
    xInt2 = xRef1.RunMethod("getChildCount")
    For xInt1 = 0 To xInt2 - 1
        xRef2.Target = xRef1.RunMethod2("getChildTabViewAt", xInt1, "java.lang.int")
      xRef2.RunMethod4("setPadding", Array As Object(Left, Top, Right, Bottom), Array As String("java.lang.int", "java.lang.int", "java.lang.int", "java.lang.int"))
        Next
  End Sub
Might help adjusting. Just call after adding your tabs.
 

RjCl

Member
Licensed User
Longtime User

Wow, thanks so much ! It worked !
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…