我可以在自定义标签视图中使用默认标签样式吗?

时间:2011-11-25 15:45:09

标签: android tabs android-tabhost

我的主要活动是TabActivity,但我的标签不需要图标。我知道我可以使用重载的TabHost.TabSpec.setIndicator(CharSequence label)方法省略该图标,如this question中所述。

但是图标所在的空间仍然保留,因此浪费了大量空间。这已在this question中注明。看来我不能只降低标签高度。我必须提供自己的View TabHost.TabSpec.setIndicator(View view)重载。

很好,但我想确保其余的样式(背景/着色)在所有设备上始终保持“android”,就像我使用了默认的标签指示器一样。所以我不想提供自己的颜色。

我发现@android:color/tab_indicator_text并将其用于TextView的文字颜色似乎按预期工作。但我不知道从哪里获得默认的tab-background-colors。我还发现了@android:style/Widget.TabWidget样式,但是将其应用于TextView和周围的LinearLayout似乎都没有帮助。

这是我的标签指示器视图xml文件,取自一些教程:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/tabLayout"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center"
    android:padding="12dip" >

    <TextView
        android:id="@+id/tabText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@android:color/tab_indicator_text" />
</LinearLayout>

如何获得'android default'选项卡样式?


修改接下来,我尝试通过setIndicator(CharSequence)添加默认标签,获取其指标视图的getBackground drawable,清除所有标签,添加我的自定义视图(见上文),然后将我在setBackground中检索到的drawable用于新指标。

结果看起来很正确,有点不对劲。首先,它们太高了,所以我什么都没得到。另一方面,所有选项卡的背景状态现在以某种方式链接(活动,突出显示,选择等)。在drawable(s)上使用mutate()根本没有帮助。下一个技巧:我添加了三个默认选项卡,获取了所有背景,清除了它们,并为每个选项卡分别提供了三个选项卡。

嗯,这解决了第二个问题。他们的州不再联系在一起。但它们仍然太高了。所以我使用TabWidget降低了updateViewLayout的高度。这样做有效,但在标签指示器的顶部留下了变色条。

实际上,我最终遇到与使用TabHost.TabSpec.setIndicator(CharSequence label)方法时相同的情况。无论如何,所有这些黑客让我觉得很脏。是不是有一种优雅的方式来在自定义视图上获得默认的android样式?

5 个答案:

答案 0 :(得分:10)

此代码取自android来源 tab_indicator.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="0dip"
    android:layout_height="64dip"
    android:layout_weight="1"
    android:layout_marginLeft="-3dip"
    android:layout_marginRight="-3dip"
    android:orientation="vertical"
    android:background="@android:drawable/tab_indicator">

    <ImageView android:id="@+id/icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
    />

    <TextView android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        style="?android:attr/tabWidgetStyle"
    />

</RelativeLayout>

您可以尝试使用此代码,删除ImageView,将layout_centerHorizontal中的TextView更改为layout_center,减少RelativeLayout的高度,并在TabHost.TabSpec.setIndicator(View view)中提供此视图。只有@android资源的引用,因此您不需要创建任何drawables或文本样式。

修改

标签指示器的标准android可绘制背景在应用程序中不可见,但可以这样做:

TabSpec tc = getTabHost().newTabSpec("tag");
tc.setIndicator("indicator1");
tc.setContent(content);
getTabHost().addTab(tc);
getTabHost().findViewById(android.R.id.icon).setVisibility(View.GONE);
TextView tv = (TextView) getTabHost().findViewById(android.R.id.title);
RelativeLayout.LayoutParams rllp = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
rllp.addRule(RelativeLayout.CENTER_IN_PARENT);
tv.setLayoutParams(rllp);

然后可以减少标签的高度:

RelativeLayout parent = ((RelativeLayout) tv.getParent());
ViewGroup.LayoutParams vglp = parent.getLayoutParams();
vglp.height = android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
parent.setLayoutParams(vglp);

结果将是:this

答案 1 :(得分:2)

我认为最好的选择是使用名为selectors的xml文件(您将放在“drawable”文件夹中)自定义Tabs方面,在“layout”文件夹上自定义tab_indicator.xml,文本样式和使用这种风格的主题。

这是tab_indicator_selector.xml,它位于“drawable”文件夹中,并且是tab_indicator.xml所必需的:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Non focused states ... -->
    <!-- Focused states ... -->
    <!-- Pressed -->
    <item android:state_selected="true" android:state_pressed="true"    android:drawable="@drawable/tab_pressed" />
    <item android:state_pressed="true" android:drawable="@drawable/tab_pressed" />
</selector>

这是tab_pressed.xml状态选择器:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:top="53dp">
        <shape android:shape="rectangle">
            <solid android:color="@color/white" />
        </shape>
    </item>
    <item android:top="53dp" android:bottom="1dp">
        <shape android:shape="rectangle">
            <solid android:color="@color/white" />
        </shape>
    </item>
    <item android:left="2dp" android:right="2dp"> 
        <shape android:shape="rectangle">
            <gradient android:angle="90" 
                android:startColor="@color/black"
                android:endColor="@color/white" />
            <stroke android:width="2dp" android:color="@color/red" />
        </shape>
    </item>
</layer-list>

可以通过创建tab_focused.xml,tab_selected.xml和tab_unseleceted.xml并设置正确的android:state_XXX组合来实现其他状态。

tab_indicator是这样的:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="0dip" 
    android:layout_height="52dip" <!-- Control the height of the Tab here! -->
    android:layout_weight="1"
    android:orientation="vertical"
    android:background="@drawable/tab_indicator_selector" 
    android:layout_marginTop="2dp"
    android:padding="2dp">

   <!-- Generally here goes an ImageView, but you said you don't want it. -->

    <TextView android:id="@+id/tab_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" 
        android:textSize="11dp" 
        android:textStyle="bold" 
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        style="?android:attr/tabWidgetStyle"
    />    
</RelativeLayout>

在实施方面,应该如下所示:

private void setTabs(){
    tabHost = getTabHost();
    addTab(R.string.tab_title_something, R.drawable.tab_something_selector, new Intent().setClass(this, PlacesNearbyTab.class));
}

private void addTab(int labelId, int drawableId, Intent intent) {
    TabHost.TabSpec spec = tabHost.newTabSpec("tab" + labelId);
    View tabIndicator = LayoutInflater.from(this).inflate(R.layout.tab_indicator, getTabWidget(), false);
    TextView title = (TextView) tabIndicator.findViewById(R.id.tab_title);
    title.setText(labelId);
    spec.setIndicator(tabIndicator);
    spec.setContent(intent);
    tabHost.addTab(spec);

}

我希望它有所帮助。这是一个很长的解决方案,但是当应用程序增长或者想要在版本2上更改其外观时,使用主题和样式非常方便。

最后,我建议您查看新的SDK版本14和Holo主题。 Holo上的标签既可以用于平板电脑也可以用于手机,你可以使用和不使用图标来制作它们。

答案 2 :(得分:0)

我不确定这是否会使文本居中,但您可以在不更改默认Android背景的情况下更改标签的高度。

试试这个:

TabHost tabs = //initialize your TabHost here
tabs.setup();
TabSpec tspec1 = tabs.newTabSpec("First Tab");
tspec1.setIndicator("Actions");
tabs.addTab(tspec1);


tabs.getTabWidget.getChildAt(0).getLayoutParams().height = (int) (35 * 1.5);

其中35是以像素为单位的高度,乘以1.5使得高度为35dp。

祝你好运。

答案 3 :(得分:0)

您是否可以尝试以下示例代码,这些代码取自默认的tab_indicator.xml,并根据您描述的需求进行略微修改。 谢谢!

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="0dip"
android:layout_height="64dip"
android:layout_weight="1"
android:layout_marginLeft="-3dip"
android:layout_marginRight="-3dip"
android:gravity="center"
android:background="@android:drawable/tab_indicator">

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        style="?android:attr/tabWidgetStyle">
    </TextView>

</LinearLayout>

答案 4 :(得分:0)

你可以在/ path-to-android-sdk / platforms /下找到每个平台的res颜色文件,你可以使用@android:style /或@android:color /来访问XML中的默认资源...

但正如您所提到的,您知道TabWidgets和其他Android UI视图的颜色和样式在不同版本之间以及设备品牌之间都有所不同。

即使你可以做你想做的事情,你的标签在版本和设备品牌之间也会有所不同......通常情况并非如此。

我会使用给定的解决方案之一实现自己的Tab样式。祝你好运!