Tuesday, January 17, 2012

Android - TabHost


I have a tabhost implemented with three tabs and are functioning. What I wanted to know if there is any way back when to click the same tab is selected, it returns to its initial state (like a reset)?



I managed to do this using the method "setOnClickListener" of each tab and start to get a new activity, but it does not matter because I notice the passage of activity.



Thanks

2 comments:

  1. I have one ugly easy way and one more complex way.

    // Re-clickable (active) tabs
    getTabWidget().getChildAt(0).setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
    if (tabHost.getCurrentTab() == 0) {
    // Try this :
    tabHost.setCurrentTab(1); // Ugly easy way
    tabHost.setCurrentTab(0);

    // Or do this :
    SomeActivityGroup.group.onResume(); // More complex way
    } else {
    tabHost.setCurrentTab(0);
    }
    }
    }


    I have little time now, if you like I can post the ActivityGroup code as well later.

    ** Here it is then:

    import java.util.ArrayList;

    import android.app.ActivityGroup;
    import android.content.Intent;
    import android.os.Bundle;
    import android.view.View;

    public class SomeActivityGroup extends ActivityGroup {

    View rootView;

    // Keep this in a static variable to make it accessible for all the nested
    // activities, lets them manipulate the view
    public static SomeActivityGroup group;

    // Need to keep track of the history if you want the back-button to work
    // properly, don't use this if your activities requires a lot of memory.
    private ArrayList<View> history;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    }

    @Override
    protected void onResume() {

    super.onResume();
    this.history = new ArrayList<View>();
    group = this;

    // Start the root activity within the group and get its view
    View view = getLocalActivityManager().startActivity("SomeActivity", new Intent(this, SomeActivity.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)).getDecorView();

    // Replace the view of this ActivityGroup
    replaceView(view);
    }

    public void replaceView(View v) {
    // Adds the old one to history
    if (history.size() == 0) {
    if (rootView != null) {
    history.add(rootView);
    rootView = null;
    }
    }
    history.add(v);
    // Changes this Groups View to the new View.
    setContentView(v);
    }

    public void back() {
    try {
    if (history.size() > 0) {
    history.remove(history.size() - 1);
    setContentView(history.get(history.size() - 1));
    } else {
    finish();
    }
    } catch (Exception ex) {
    }
    }

    @Override
    public void onBackPressed() {
    try {
    SomeActivityGroup.group.back();
    } catch (Exception ex) {

    }
    return;
    }

    }


    Just keep in mind that ActivityGroups are deprecated in ICS.

    ReplyDelete
  2. If you develop a new application then I strongly recommend you to use Fragments and some compatibility library, preferably ActionBarSherlock, because the "old" approach with TabHost and TabActivities is deprecated now.

    Download the library and take a look at class:

    ABSLibraryXX\samples\demos\src\com\actionbarsherlock\sample\demos\app\FragmentTabs.java

    I guarantee you will be surprised how powerful and simple it is. When you are switching between Fragments instead of Activities, then the Fragments state persist - they behave like views rather than activities.

    ReplyDelete