Android 自定义选项卡/视图-TabHost还是ActivityGroup?

Android 自定义选项卡/视图-TabHost还是ActivityGroup?,android,android-tabhost,Android,Android Tabhost,我正在构建一个选项卡式应用程序。TabHost的工作非常出色。不幸的是,我的团队领导不喜欢标签的外观。他不喜欢小图标和标签之间的间隙。因此,我需要修改TabHost或使用ActivityGroup 我的第一次尝试是改变TabHost 这是我的一个标签的可绘图页: <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"&g

我正在构建一个选项卡式应用程序。TabHost的工作非常出色。不幸的是,我的团队领导不喜欢标签的外观。他不喜欢小图标和标签之间的间隙。因此,我需要修改TabHost或使用ActivityGroup

我的第一次尝试是改变TabHost

这是我的一个标签的可绘图页:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- When selected, use grey -->
    <item android:drawable="@drawable/ic_tab_timeline_grey"
          android:state_selected="true" />
    <!-- When not selected, use white-->
    <item android:drawable="@drawable/ic_tab_timeline_white" />
    <!-- This is a state-list drawable, which you will apply as the tab image. When the tab state changes, the tab icon will automatically switch between the images defined here.  -->
</selector>
(请注意,我将指示器设置为空白。)

然后,我设置背景图像:

TabWidget tw = getTabWidget();
//changeTabWidgetStyle(tw);
View tempView = tabHost.getTabWidget().getChildAt(0);
tempView.setBackgroundDrawable(getResources().getDrawable(R.drawable.timeline_on));
这成功地将背景设置为我想要的图像。然而,我的标签上仍然有一个小图标,它覆盖在我的背景图像上。我怎样才能摆脱图标?我尝试在初始化选项卡时将Drawable设置为null,但这会导致我的应用程序崩溃

即使我可以让它工作,看起来我仍然会有标签之间的空间。我怎样才能摆脱这些

如果这不起作用,我可能不得不参加一个活动小组。不过,我宁愿不这样做,因为这似乎更复杂

我用这个例子:


我可以让“标签”更改和膨胀布局,但我不能添加本地活动。我不确定要将视图添加到哪种“容器”。我的xml布局应该是什么样的?

下面是我用来成功地在最近的项目上创建完全自定义外观的选项卡的方法

其思想是在布局中使用隐藏的TabWidget,并使用自定义的包含按钮的LinearLayout对其进行控制。这样,您可以更轻松地自定义按钮,使其外观符合您的要求。您将在每个按钮的OnClick中控制活动中的实际TabWidget

使用TabWidget和按钮创建布局:

<?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">

<RelativeLayout android:orientation="vertical"
    android:layout_width="fill_parent" android:layout_height="fill_parent"
    android:gravity="bottom">
    <TabWidget android:id="@android:id/tabs"
        android:layout_width="fill_parent" android:layout_height="wrap_content"
        android:visibility="gone" />

    <LinearLayout android:id="@+id/tabbar"
        android:orientation="horizontal" android:layout_width="fill_parent"
        android:layout_height="wrap_content">
        <Button android:id="@+id/firstButton"
            android:layout_alignParentTop="true" android:background="@drawable/btn_first_on"
            android:layout_width="100dp" android:layout_height="43dp"
            android:clickable="true"></Button>
        <Button android:id="@+id/secondButton"
            android:layout_alignParentTop="true" android:background="@drawable/btn_second_off"
            android:layout_height="43dp" android:layout_width="100dp"
            android:clickable="true"></Button>
        <Button android:id="@+id/thirdButton"
            android:layout_alignParentTop="true" android:background="@drawable/btn_third_off"
            android:layout_height="43dp" android:layout_width="100dp"
            android:clickable="true"></Button>
        <Button android:id="@+id/forthButton"
            android:layout_alignParentTop="true" android:background="@drawable/btn_forth_off"
            android:layout_height="43dp" android:layout_width="100dp"
            android:clickable="true"></Button>
    </LinearLayout>

    <FrameLayout android:id="@android:id/tabcontent"
        android:layout_width="fill_parent" android:layout_height="fill_parent"
        android:layout_below="@+id/tabbar" />

    </RelativeLayout>
</TabHost>
正如你所看到的,我正在使用可绘制的按钮图像和关闭。使用此技术,您不必仅限于在尝试自定义TabWidget选项卡的外观时可用的选项,您可以为选项卡创建完全自定义的外观


此外,根据经验,在android选项卡中使用ActivityGroup是个坏主意。这种方法消耗了大量的系统资源。一种更好的方法,也是我在这个项目上实现的方法,就是通过一组视图跟踪视图,然后根据需要将它们调出。

以下是我用来成功地在最近的项目上创建完全自定义的选项卡的方法

其思想是在布局中使用隐藏的TabWidget,并使用自定义的包含按钮的LinearLayout对其进行控制。这样,您可以更轻松地自定义按钮,使其外观符合您的要求。您将在每个按钮的OnClick中控制活动中的实际TabWidget

使用TabWidget和按钮创建布局:

<?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">

<RelativeLayout android:orientation="vertical"
    android:layout_width="fill_parent" android:layout_height="fill_parent"
    android:gravity="bottom">
    <TabWidget android:id="@android:id/tabs"
        android:layout_width="fill_parent" android:layout_height="wrap_content"
        android:visibility="gone" />

    <LinearLayout android:id="@+id/tabbar"
        android:orientation="horizontal" android:layout_width="fill_parent"
        android:layout_height="wrap_content">
        <Button android:id="@+id/firstButton"
            android:layout_alignParentTop="true" android:background="@drawable/btn_first_on"
            android:layout_width="100dp" android:layout_height="43dp"
            android:clickable="true"></Button>
        <Button android:id="@+id/secondButton"
            android:layout_alignParentTop="true" android:background="@drawable/btn_second_off"
            android:layout_height="43dp" android:layout_width="100dp"
            android:clickable="true"></Button>
        <Button android:id="@+id/thirdButton"
            android:layout_alignParentTop="true" android:background="@drawable/btn_third_off"
            android:layout_height="43dp" android:layout_width="100dp"
            android:clickable="true"></Button>
        <Button android:id="@+id/forthButton"
            android:layout_alignParentTop="true" android:background="@drawable/btn_forth_off"
            android:layout_height="43dp" android:layout_width="100dp"
            android:clickable="true"></Button>
    </LinearLayout>

    <FrameLayout android:id="@android:id/tabcontent"
        android:layout_width="fill_parent" android:layout_height="fill_parent"
        android:layout_below="@+id/tabbar" />

    </RelativeLayout>
</TabHost>
正如你所看到的,我正在使用可绘制的按钮图像和关闭。使用此技术,您不必仅限于在尝试自定义TabWidget选项卡的外观时可用的选项,您可以为选项卡创建完全自定义的外观


此外,根据经验,在android选项卡中使用ActivityGroup是个坏主意。这种方法消耗了大量的系统资源。一个更好的方法,也是我在这个项目上实现的方法,是通过一组视图跟踪视图,然后根据需要将它们调出。

根据SBerg413的回答,您可以将新选项卡按钮的按钮图像设置为透明图像。然后添加一个
ImageView
以显示在按钮下(使用
RelativeLayout
使
ImageView
显示在与按钮相同的空间中),然后根据按下的按钮切换显示的图像


通过这种方式,您可以拥有不同形状的选项卡按钮,通常选项卡栏的设计更加自由,并将这些按钮用作每个选项卡按钮的基本点击框。

根据SBerg413的回答,您可以将新选项卡按钮的按钮图像设置为透明图像。然后添加一个
ImageView
以显示在按钮下(使用
RelativeLayout
使
ImageView
显示在与按钮相同的空间中),然后根据按下的按钮切换显示的图像


通过这种方式,您可以拥有不同形状的选项卡按钮,通常选项卡栏的设计更加自由,并将这些按钮用作每个选项卡按钮的基本点击框。

用户经常指责Android开发人员不关心平台保真度,Android应用程序看起来都不一样。安卓标签可能不是最美观的,但如果你按原样使用它们,你可以获得与其他应用程序的一致性和逼真度,而用户实际上似乎很关心这些应用程序。如果安卓在未来的安卓版本中更新L&F标签,你的标签也会随之更新。因此,我建议您的团队负责人考虑用户想要什么,而不是团队负责人想要什么。用户经常指责Android开发人员不关心平台保真度,Android应用程序看起来都不一样。安卓标签可能不是最美观的,但如果你按原样使用它们,你可以获得与其他应用程序的一致性和逼真度,而用户实际上似乎很关心这些应用程序。如果安卓在未来的安卓版本中更新L&F标签,你的标签也会随之更新。因此,我建议您的团队领导考虑用户想要什么,而不是团队领导想要什么。
<?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">

<RelativeLayout android:orientation="vertical"
    android:layout_width="fill_parent" android:layout_height="fill_parent"
    android:gravity="bottom">
    <TabWidget android:id="@android:id/tabs"
        android:layout_width="fill_parent" android:layout_height="wrap_content"
        android:visibility="gone" />

    <LinearLayout android:id="@+id/tabbar"
        android:orientation="horizontal" android:layout_width="fill_parent"
        android:layout_height="wrap_content">
        <Button android:id="@+id/firstButton"
            android:layout_alignParentTop="true" android:background="@drawable/btn_first_on"
            android:layout_width="100dp" android:layout_height="43dp"
            android:clickable="true"></Button>
        <Button android:id="@+id/secondButton"
            android:layout_alignParentTop="true" android:background="@drawable/btn_second_off"
            android:layout_height="43dp" android:layout_width="100dp"
            android:clickable="true"></Button>
        <Button android:id="@+id/thirdButton"
            android:layout_alignParentTop="true" android:background="@drawable/btn_third_off"
            android:layout_height="43dp" android:layout_width="100dp"
            android:clickable="true"></Button>
        <Button android:id="@+id/forthButton"
            android:layout_alignParentTop="true" android:background="@drawable/btn_forth_off"
            android:layout_height="43dp" android:layout_width="100dp"
            android:clickable="true"></Button>
    </LinearLayout>

    <FrameLayout android:id="@android:id/tabcontent"
        android:layout_width="fill_parent" android:layout_height="fill_parent"
        android:layout_below="@+id/tabbar" />

    </RelativeLayout>
</TabHost>
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    // tabs        
    firstButton = (Button) findViewById(R.id.firstButton);
    secondButton = (Button) findViewById(R.id.secondButton);        
    thirdButton = (Button) findViewById(R.id.thirdButton);
    forthButton = (Button) findViewById(R.id.forthButton);

    Resources res = getResources(); // Resource object to get Drawables
    final TabHost tabHost = getTabHost();  // The activity TabHost
    TabHost.TabSpec spec;  // Resusable TabSpec for each tab
    Intent intent;  // Reusable Intent for each tab

    intent = new Intent().setClass(this, FirstGroupActivity.class);
    spec = tabHost.newTabSpec("first").setIndicator("First").setContent(intent);
    tabHost.addTab(spec);
    intent = new Intent().setClass(this, SecondGroupActivity.class);
    spec = tabHost.newTabSpec("second").setIndicator("Second").setContent(intent);
    tabHost.addTab(spec);   

    intent = new Intent().setClass(this, ThirdGroupActivity.class);
    spec = tabHost.newTabSpec("third").setIndicator("Third").setContent(intent);
    tabHost.addTab(spec);


    intent = new Intent().setClass(this, ForthActivity.class);
    spec = tabHost.newTabSpec("forth").setIndicator("Forth").setContent(intent);
    tabHost.addTab(spec);


    tabHost.setCurrentTab(0);

    firstButton.setOnClickListener(new OnClickListener() {

        public void onClick(View v)
        {
            tabHost.setCurrentTab(0);
            firstButton.setBackgroundResource(R.drawable.btn_first_on);
            secondButton.setBackgroundResource(R.drawable.btn_second_off);              
            thirdButton.setBackgroundResource(R.drawable.btn_third_off);
            forthButton.setBackgroundResource(R.drawable.btn_forth_off);            
        }

    });


    secondButton.setOnClickListener(new OnClickListener() {

        public void onClick(View v)
        {
            tabHost.setCurrentTab(1);
            firstButton.setBackgroundResource(R.drawable.btn_first_off);
            secondButton.setBackgroundResource(R.drawable.btn_second_on);                       
            thirdButton.setBackgroundResource(R.drawable.btn_third_off);                        
            forthButton.setBackgroundResource(R.drawable.btn_forth_off);

        }

    });


    thirdButton.setOnClickListener(new OnClickListener() {

        public void onClick(View v)
        {
            tabHost.setCurrentTab(3);
            firstButton.setBackgroundResource(R.drawable.btn_first_off);
            secondButton.setBackgroundResource(R.drawable.btn_second_off);              
            thirdButton.setBackgroundResource(R.drawable.btn_third_on);
            forthButton.setBackgroundResource(R.drawable.btn_forth_off);

        }

    });


    forthButton.setOnClickListener(new OnClickListener() {

        public void onClick(View v)
        {
            tabHost.setCurrentTab(4);
            firstButton.setBackgroundResource(R.drawable.btn_first_off);
            secondButton.setBackgroundResource(R.drawable.btn_second_off);              
            thirdButton.setBackgroundResource(R.drawable.btn_third_off);
            forthButton.setBackgroundResource(R.drawable.btn_forth_on);

        }

    });
}