TabHost/TabWidget - 缩放背景图像?

问题描述:

我需要缩放我的TabWidget背景图片,以保持宽高比。
我正在使用TabWidget的TabHost。然后我使用setBackgroundDrawable来设置图像。TabHost/TabWidget - 缩放背景图像?

我在这里发现了一个很接近的答案 - Background in tab widget ignore scaling。但是,我不确定在哪里添加新的Drawable代码。 (使用HelloTabWidget示例,我的模块都没有使用RelativeLayout,并且我没有看到“tabcontent”的任何布局。)

我还发现此线程 - Android: Scale a Drawable or background image?。据它说,这听起来像我将不得不预先缩放我的图像,这打破了使它们可扩展的整体目的。

我还发现另一个线程,其中有人划分了Drawable类,所以它不会缩放,或者它可以正确缩放。我现在找不到它,但是当你只需要做一些像mTab.setScaleType(centerInside)这样简单的工作时,这看起来就像是一个很好的选择。

这里是我的代码:

的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> 

主要活动:

 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)); 
} 

我也试过9patch图像,但是它们将是太小了。

那么,最好的方法是什么呢?

我怀疑你努力寻找开箱即用的方法来执行背景图像缩放的原因是,它通常不被视为良好的做法。图像缩放往往会引入工件和条纹,这会使您的界面看起来很讨厌。这个例外是在一个Imageview中,但我认为这个类提供的伸缩支持更多的是支持像照片或网页内容(即你的应用没有附带的图片)。

您的用户界面布局的设计应该使得任何基于资源的背景图像都应该按照设备密度/屏幕尺寸的正确分辨率进行预先缩放。换句话说,您应该使用Supporting Multiple Screens开发指南中概述的资源文件夹命名约定来提供每个drawable的多个版本以满足多个屏幕密度和大小。

然后应布置用户界面,以便设备之间屏幕尺寸的任何细微差异都可以处理,而无需缩放其包含的视图的背景图像。很显然,我不知道你提出的用户界面是什么样子,所以很难提出具体的建议,但通常我使用简单的背景块颜色或动态填充视图之间的空间。

但是,如果你真的确定你想要扩展你的背景图片,尽管上面讲道:-),为什么不尝试使用ScaleDrawable来包装你现有的drawable?

如果您知道这两个视图和背景图像绘制的高度和宽度,那么你可以这样做:

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

检查了这一点,让我知道它是否为你工作。

Custom Android Tab