自定义标签/视图 - TabHost或ActivityGroup?

时间:2010-10-14 17:59:03

标签: android android-tabhost

我正在构建一个标签式应用程序。使用TabHost可以很好地完成工作。不幸的是,我的团队负责人不喜欢标签的外观。他不喜欢小图标和标签之间的间隙。所以,我要么需要修改TabHost,要么使用ActivityGroup。

我的第一次尝试是改变TabHost。

以下是我的一个标签的drawable:

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

我在主要活动中初始化标签:

// Initialize a TabSpec for each tab and add it to the TabHost
intent = new Intent().setClass(this, TimelineActivity.class);
spec = tabHost.newTabSpec("timeline") .setIndicator("",
                  res.getDrawable(R.drawable.ic_tab_timeline))
              .setContent(intent);
tabHost.addTab(spec);

(请注意,我将指标设置为空白。)

然后,我设置了背景图片:

TabWidget tw = getTabWidget();
//changeTabWidgetStyle(tw);
View tempView = tabHost.getTabWidget().getChildAt(0);
tempView.setBackgroundDrawable(getResources().getDrawable(R.drawable.timeline_on));

这会成功将背景设置为我想要的图像。但是,我的标签仍然有一个小图标,它覆盖了我的背景图像。我怎样摆脱这个图标?我在初始化选项卡时尝试将Drawable设置为null,但这会导致我的应用程序崩溃。

即使我可以让它工作,看起来我仍然会在标签之间留有空格。我该怎样摆脱那些?

如果这不起作用,我可能不得不使用ActivityGroup。但我不愿意,因为这看起来更复杂。

我正在使用此示例:android: using ActivityGroup to embed activities

LocalActivityManager mgr = getLocalActivityManager(); 

Intent i = new Intent(this, SomeActivity.class); 

Window w = mgr.startActivity("unique_per_activity_string", i); 
View wd = w != null ? w.getDecorView() : null; 

if(wd != null) { 
    mSomeContainer.addView(wd); 
} 

我可以通过“标签”来更改和扩充布局,但我无法添加本地活动。我不确定添加视图的是什么类型的“容器”。我的xml布局应该是什么样的?

2 个答案:

答案 0 :(得分:1)

以下是我成功在最近的项目中成功创建完全自定义标签的方法。

我们的想法是在您的布局中使用隐藏的TabWidget,并使用包含Buttons的自定义LinearLayout控制它。这样,您可以更轻松地自定义按钮,无论您喜欢什么。您将在每个按钮的OnClick中控制Activity中的实际TabWidget。

使用TabWidget和Buttons创建布局:

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

设置活动的onCreate以使用按钮调整选项卡视图来处理:

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

        }

    });
}

正如您所看到的,我正在使用drawables打开和关闭按钮的图像。使用这种技术,您不仅可以选择自定义TabWidget选项卡外观的选项,还可以为选项卡创建完全自定义的外观。

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

答案 1 :(得分:0)

除了SBerg413的答案之外,您还可以将新标签按钮的按钮图像设置为透明图像。然后添加ImageView以显示在按钮下方(使用RelativeLayout以使ImageView出现在与按钮相同的空间中)并根据哪个按钮切换显示在那里的图像按压。

通过这种方式,您可以使用不同形状的标签按钮,通常可以更自由地设置标签栏,并将按钮用作每个标签按钮的基本点击框。