zhulik
zhulik

Reputation: 133

Simple tabs in android

How to implement in android simple tabs without any Intents or Views(like in TabHost)?

I need only tab headers and want to listen how tab index changes.

Or advise me how to implement multiposition switches.

UPD: I use api v14 and ActionBar tabs already used for another purpose.

Upvotes: 0

Views: 681

Answers (3)

Dongie Agnir
Dongie Agnir

Reputation: 612

I had a similar project a while back where I just needed to listen for tab changes. Here is a great example from Google:

public class MyPagerAdapter extends FragmentPagerAdapter
        implements TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener {
    private final Context mContext;
    private final TabHost mTabHost;
    private final ViewPager mViewPager;

private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();

private class TabInfo {
    @SuppressWarnings("unused")
    private final String tag;
    private final Class<?> clss;
    private final Bundle args;

    public TabInfo(String _tag, Class<?> _clss, Bundle _args) {
        tag = _tag;
        clss = _clss;
        args = _args;       
            }
}

private class DummyFactory implements TabHost.TabContentFactory {

    private final Context mContext;

    public DummyFactory(Context context) {
        mContext = context;
    }
    public View createTabContent(String tag) {
        View v = new View(mContext);
        v.setMinimumHeight(0);
        v.setMinimumWidth(0);
        return v;
    }

}
public MyPagerAdapter(FragmentActivity activity, TabHost tabHost, ViewPager viewPager) {
    super(activity.getSupportFragmentManager());

    mContext = activity;
    mTabHost = tabHost;
    mViewPager = viewPager;

    mTabHost.setOnTabChangedListener(this);
    mViewPager.setAdapter(this);
    mViewPager.setOnPageChangeListener(this);
}

public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) {
    tabSpec.setContent(new DummyFactory(mContext));

    String tag = tabSpec.getTag();

    TabInfo tab = new TabInfo(tag, clss, args);
    mTabs.add(tab);
    mTabHost.addTab(tabSpec);
    this.notifyDataSetChanged();

}

@Override
public Fragment getItem(int i) {
    TabInfo tab = mTabs.get(i);
    Fragment fragment = Fragment.instantiate(mContext, tab.clss.getName(), tab.args);
    Log.d("DEBUG", "getItem from view pager called returning hash: " + fragment.hashCode());
    return fragment;
}

@Override
public int getCount() {

    return mTabs.size();
}

public void onPageScrollStateChanged(int arg0) {
    // TODO Auto-generated method stub

}

public void onPageScrolled(int arg0, float arg1, int arg2) {
    // TODO Auto-generated method stub

}


public void onPageSelected(int position) {
    // Unfortunately when TabHost changes the current tab, it kindly
    // also takes care of putting focus on it when not in touch mode.
    // The jerk.
    // This hack tries to prevent this from pulling focus out of our
    // ViewPager.
    TabWidget widget = mTabHost.getTabWidget();
    int oldFocusability = widget.getDescendantFocusability();
    widget.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
    mTabHost.setCurrentTab(position);
    widget.setDescendantFocusability(oldFocusability);
}

public void onTabChanged(String tabId) {
    int position = mTabHost.getCurrentTab();

    mViewPager.setCurrentItem(position);

}
 }

The relevant parts here is that the adapter implements TabHost.OnTabChangeListener and in the body of the constructor, the onTabChangedListener is set accordingly (mTabHost.setOnTabChangedListener(this))

You will also notice the inner class DummyFactory

private class DummyFactory implements TabHost.TabContentFactory {

    private final Context mContext;

    public DummyFactory(Context context) {
        mContext = context;
    }
    public View createTabContent(String tag) {
            View v = new View(mContext);
        v.setMinimumHeight(0);
        v.setMinimumWidth(0);
        return v;
    }
}

Which is used in addTab to create a content view with height and width of 0, which allows you to add your actual content under the TabHost in your layout.

Upvotes: 0

Vinay W
Vinay W

Reputation: 10190

here's an example

suppose se01,se02 and se03 are three buttons in a horizontal LinearLayout or ScrollView(if you want to support more tabs). So, you could set onClickListeners on each of the Buttons and program them to switch to a specific background (which could show the tab is selected) on click. That's the simplest way to do it. Here's a code snippet, which is quite easy to understand. Hope this helps :-)

            //initialize the first button to be 'selected' when the activity is started by a background which is similar to the other buttons but shows the selected button/tab as highlighted.

    se01.setBackgroundResource(R.drawable.popup_full_dark2);
    lastClicked = (Button) findViewById(R.id.ph_s01);//this keeps a track of the last tab/button pressed
    toSe01();// a function which performs the changes to the view with respect to the tab selected

    //Listeners
    se01.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if (v.getId() != lastClicked.getId()) {
                lastClicked
                        .setBackgroundResource(R.drawable.popup_bottom_dark);//changes the background to show the tab is selected
                v.setBackgroundResource(R.drawable.popup_full_dark2);
                lastClicked = se01;
                s.startAnimation(new Animation9());
                toSe01();
                s.scrollTo(0, 0);
            }
        }
    });
    se02.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            // TODO Auto-generated method stub
            if (v.getId() != lastClicked.getId()) {
                lastClicked
                        .setBackgroundResource(R.drawable.popup_bottom_dark);
                v.setBackgroundResource(R.drawable.popup_full_dark2);
                lastClicked = se02;
                s.startAnimation(new Animation9());
                toSe02();
                s.scrollTo(0, 0);
            }
        }
    });
    se03.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            // TODO Auto-generated method stub
            if (v.getId() != lastClicked.getId()) {
                lastClicked
                        .setBackgroundResource(R.drawable.popup_bottom_dark);
                v.setBackgroundResource(R.drawable.popup_full_dark2);
                lastClicked = se03;
                s.startAnimation(new Animation9());
                toSe03();
                s.scrollTo(0, 0);
            }
        }
    });

Upvotes: 0

Bryan Herbst
Bryan Herbst

Reputation: 67189

The simplest solution (in my opinion, of course) would be to simply use three different ImageViews or Buttons to mimick "tabs." You can swap out an "unselected tab" image for a "selected tab" image as necessary.

As far as I am aware, there is no simple way outside of TabHosts and other such solutions requiring Activities, Fragments, or Views for the different tabs.

Upvotes: 1

Related Questions