TabHost / TabWidget - scale background image?

I need to scale the background images of TabWidget so that they maintain aspect ratio.
I am using TabHost with TabWidget. Then I use setBackgroundDrawable to set the images.

I found a close answer here - Backgrounds in tab widgets ignore scaling . However, I'm not sure where to add the new Drawable code. (Using the HelloTabWidget example, none of my modules use RelativeLayout, and I don't see any layout for "tabcontent".)

I also found this theme - Android: scale graphic or background image? . According to him, it seems that I will have to scale my images in advance, which harms the entire goal of making them scalable.

I also found another thread in which someone subclassed the Drawable class so that it does not scale, or it scales properly. I can't find it now, but it seems like a LOT to get by when you just have to do something simple, like mTab.setScaleType (centerInside).

Here is my code:

main.xml:

<?xml version="1.0" encoding="utf-8"?> <TabHost xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/tabhost" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/main_background"> <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <FrameLayout android:id="@android:id/tabcontent" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1"/> <TabWidget android:id="@android:id/tabs" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="0"/> </LinearLayout> </TabHost> 

Primary activity:

  tabHost.setOnTabChangedListener(new OnTabChangeListener() { TabHost changedTabHost = getTabHost(); TabWidget changedTabWidget = getTabWidget(); View changedView = changedTabHost.getTabWidget().getChildAt(0); public void onTabChanged(String tabId) { int selectedTab = changedTabHost.getCurrentTab(); TabWidget tw = getTabWidget(); if(selectedTab == 0) { //setTitle("Missions Timeline"); View tempView = tabHost.getTabWidget().getChildAt(0); tempView.setBackgroundDrawable(getResources().getDrawable(R.drawable.tab_timeline_on)); tempView = tabHost.getTabWidget().getChildAt(1); tempView.setBackgroundDrawable(getResources().getDrawable(R.drawable.tab_map_off)); tempView = tabHost.getTabWidget().getChildAt(2); tempView.setBackgroundDrawable(getResources().getDrawable(R.drawable.tab_search_off)); tempView = tabHost.getTabWidget().getChildAt(3); tempView.setBackgroundDrawable(getResources().getDrawable(R.drawable.tab_news_off)); tempView = tabHost.getTabWidget().getChildAt(4); tempView.setBackgroundDrawable(getResources().getDrawable(R.drawable.tab_license_off)); //ImageView iv = (ImageView)tabHost.getTabWidget().getChildAt(0).findViewById(android.R.id.icon); //iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_timeline_on)); //iv = (ImageView)tabHost.getTabWidget().getChildAt(1).findViewById(android.R.id.icon); //iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_map_off)); } else if (selectedTab == 1) { //setTitle("Spinoffs Around You"); View tempView = tabHost.getTabWidget().getChildAt(0); tempView.setBackgroundDrawable(getResources().getDrawable(R.drawable.tab_timeline_off)); tempView = tabHost.getTabWidget().getChildAt(1); tempView.setBackgroundDrawable(getResources().getDrawable(R.drawable.tab_map_on)); tempView = tabHost.getTabWidget().getChildAt(2); tempView.setBackgroundDrawable(getResources().getDrawable(R.drawable.tab_search_off)); tempView = tabHost.getTabWidget().getChildAt(3); tempView.setBackgroundDrawable(getResources().getDrawable(R.drawable.tab_news_off)); tempView = tabHost.getTabWidget().getChildAt(4); tempView.setBackgroundDrawable(getResources().getDrawable(R.drawable.tab_license_off)); } 

I also tried 9patch images, but they turned out to be too small.

So what is the best way to do this?

+7
source share
2 answers

I suspect that the reason you are trying to find a ready-made way to make a background image is because it is usually not considered good practice. Image scaling tends to introduce artifacts and bandages that can make your user interface look nasty. The exception to this is Imageview, but I would say that the zoom support provided by this class is more intended to support things like photos or web content (i.e. Images that you did not send with your application).

Your interface layout should be designed so that any resource-based background images are pre-scaled to the correct resolution for the density / screen size of the device. In other words, you must provide multiple versions of each of them to cater for multiple densities and screen sizes using the resource directory naming convention described in the Multiple Screen Support guide.

Then the user interface should be laid out so that any small differences in screen size between devices can be processed without the need to scale the background images of its contained representations. Obviously, I don’t know what your proposed user interface looks like, so it’s hard to make any specific suggestions, but usually I use simple background color blocks or ShapeDrawable to dynamically fill the space between the views.

However, if you are really sure you want to scale background images despite the sermon above :-) why not try using ScaleDrawable to wrap your existing drawings?

If you know the height and width of your image and background image, you can do something like:

 Drawable backgroundDrawable = getResources().getDrawable(R.drawable.tab_license_off); tempView.setBackgroundDrawable( new ScaleDrawable( backgroundDrawable, Gravity.CENTER, tempView.getWidth() / backgroundDrawable.getIntrinsicWidth(), tempView.getHeight() / backgroundDrawable.getIntrinsicHeight()); 
0
source

Check it out and let me know if it works for you.

Android custom tab

+1
source

All Articles