开发者

Customized Tabs/Views - TabHost or ActivityGroup?

开发者 https://www.devze.com 2023-01-20 04:40 出处:网络
I am building a tabbed application.Things work wonderfully with TabHost.Unfortunately, my team lead does not like the look of the tabs.He doesn\'t like the tiny icon and the gaps between the tabs.So,

I am building a tabbed application. Things work wonderfully with TabHost. Unfortunately, my team lead does not like the look of the tabs. He doesn't like the tiny icon and the gaps between the tabs. So, I either need to modify TabHost or use an ActivityGroup.

My first attempt was at changing TabHost.

Here is the drawable for one of my tabs:

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

I initialize the tab in my main activity:

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

(Note that I set the Indicator to blanks.)

Then, I set the background image:

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

This succe开发者_StackOverflow中文版ssfully sets the background to my desired image. However, my tab still has the tiny icon, which overlays my background image. How can I get rid of the icon? I tried setting the Drawable to null when I initialize the tab, but this causes my app to crash.

Even if I can get this to work, it looks like I will still have spaces between the tabs. How can I get rid of those?

If this doesn't work, I may have to go with an ActivityGroup. I would rather not, though, because that seems more complicated.

I'm using this example: 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); 
} 

I can get the "tabs" to change and inflate layouts, but I can't add the local activity. I'm not sure what sort of "container" to add the view to. What should my xml layout look like?


Here is the method i used to successfully successfully create completely custom looking tabs on a recent project.

The idea is to use a hidden TabWidget in your layout and control it with a customized LinearLayout containing Buttons. This way, you can more easily customize the buttons to look however you'd like. You'll control the actual TabWidget in your Activity within each button's OnClick.

Create your layout with both the TabWidget and the 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>

Set up the onCreate of your activity to handle using the buttons for adjusting the tab views:

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

        }

    });
}

As you can see, I'm using drawables for the images of the buttons on and off. Using this technique, you're not limited to the options available when simply just trying to customize the look of the TabWidget's tabs and you can create a completely custom look to your tabs.

Also, as a rule of thumb, it's a bad idea to use an ActivityGroup in android tabs. That approach eats up a lot of system resources. A better approach and one that I've also implemented on this project is to keep track of the views through an array of views and then swap them out as needed.


Further to SBerg413's answer you can set the button images for your new tab buttons to transparent images. Then add an ImageView to display under the buttons (use RelativeLayout to get the ImageView to appear in the same space as the buttons) and simply switch the image displayed there depending on which button is pressed.

This way you can have tab buttons of different shapes and generally more freedom of design for the tab bar and use the buttons as a basic hit box for each tab button.

0

精彩评论

暂无评论...
验证码 换一张
取 消