I have an example with 3 tabs and one button.
public class MainActivity extends SherlockActivity implements TabListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
setContentView(R.layout.activity_main);
addTab("1", 0, false);
addTab("2", 1, false);
addTab("3", 2, false);
Button cmdClick = (Button) findViewById(R.id.cmdClick);
cmdClick.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
getSupportActionBar().setSelectedNavigationItem(0);
}
});
}
private void addTab(String tabTitle, int position, boolean setSelected) {
ActionBar.Tab tab = getSupportActionBar().newTab();
tab.setText(tabTitle);
tab.setTabListener(this);
getSupportActionBar().addTab(tab, position, setSelected);
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Log.d("example", "Selected " + tab.getPosition());
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
Log.d("example", "Unselected " + tab.getPosition());
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
Log.d("example", "Reselected " + tab.getPosition());
}
}
When I click on the button it automatically selects first tab. I would like to automatically select first tab whenever I click on the second or on the third tab. I tried like this
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Log.d("example", "Selected " + tab.getPosition());
getSupportActionBar().setSelectedNavigationItem(0);
}
but it doesn't work. Any ideas?
Thanks.
Edit:
Maybe this example doesn't have any sense but this is just a simplified example of what I'm trying to do. I would like to have 2 tabs by default, one with title "1" and second one with title "+". When user selects "+" tab I would like to create new tab with title "2" (between tabs "1" and "+") and to automatically select tab "2".
First of all I'd like to discourage this kind of behavior. This will be VERY confusing for your users and frankly doesn't make any sense.
That said I tried hacking it but it doesn't seem like it's that easy to do. I did following:
public void onTabSelected(Tab tab, FragmentTransaction ft) {
if(tab.getPosition() == 0) {
int tabs = mActivity.getSupportActionBar().getTabCount();
if(tabs > 3) {
ActionBar.Tab test = mActivity.getSupportActionBar().getTabAt(2);
test.select();
return;
}
}
Edit:
For the behavior your describing I think it would be much easier to implement it by creating your own tabs. You could use radio buttons and/or buttons to implement it easily.
Now this causes the tab indicator to still point at the old tab but the fragment inside is updated to the selected one =/ so not quite there...
Related
I have run into an obstacle when doing my Android application. My issue is that I cannot create an onTabListener for my tabs. I have three tabs with different names. The problem is that they all have the same tab count. In my code I ran this:
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
int n = getActionBar().getTabCount();
Toast.makeText(getApplicationContext(), "You have selected: " + n, Toast.LENGTH_LONG).show();
}
This makes a toast saying the value of the tab (for example: 0, 1, 2, 3), but all of the tabs have the same indicator. I cannot make an onTabListener if I have all my tabs have the same indicator. Here is my full code:
ActionBar.TabListener tabListener = new ActionBar.TabListener() {
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
int n = getActionBar().getTabCount();
Toast.makeText(getApplicationContext(), "You have selected: " + n, Toast.LENGTH_LONG).show();
}
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
// hide the given tab
}
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
// probably ignore this event
}
};
// Add 3 tabs, specifying the tab's text and TabListener
for (int i = 0; i < 3; i++) {
actionBar.addTab(
actionBar.newTab()
.setText(tabTitle[i])
.setTabListener(tabListener));
}
What is the issue? Is there any way I can create an onTabListener using the tab's title? Any help to this problem is greatly appreciated.
all you are doing is getting the number of tabs you have...
you need to do tab.getPosition() to get what one selected
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
int n = tab.getPosition();
Toast.makeText(getApplicationContext(), "You have selected: " + n, Toast.LENGTH_LONG).show();
}
I have a tabbed application built with fragments and ActionBarSherlock. I have 3 tabs, with 3 ListFragment's Here's what's happening.
When I select any tab, the onCreate method for the associated fragment is called as expected at first time but not at second. The problem is that the onCreate method is called for the next adjacent tab but not selected tab.
Click on tab2 and onCreate of tab3 is called but not tab2.
Actually my requirement is, when i change some data in tab1 means fragment1. those changes are not effected in fragment2, when i select tab2 (fragment2) it means fragment2 onCreate() was not calling. why it's not refreshing the fragment properly. this is the adapter i am using.
private class TabsAdapter extends FragmentPagerAdapter implements ViewPager.OnPageChangeListener, ActionBar.TabListener {
public TabsAdapter(FragmentActivity activity, ActionBar actionBar, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mActionBar = actionBar;
mViewPager = pager;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public void addTab(ActionBar.Tab tab, Class<?> clss, int tabId) {
mTabs.add(clss.getName());
mTabsId.add(tabId);
mActionBar.addTab(tab.setTabListener(this));
notifyDataSetChanged();
}
public Integer getIdForPosition(int position) {
if (position >= 0 && position < mTabsId.size()) {
return mTabsId.get(position);
}
return null;
}
#Override
public int getCount() {
return mTabs.size();
}
#Override
public Fragment getItem(int position) {
//TabInfo info = mTabs.get(position);
return Fragment.instantiate(mContext, mTabs.get(position), new Bundle());
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Log.i(TAG, "*******tab selected*******" +tab);
clearDetails();
if (mViewPager.getCurrentItem() != tab.getPosition()) {
mViewPager.setCurrentItem(tab.getPosition(), true);
}
}
#Override
public void onPageSelected(int position) {
mActionBar.setSelectedNavigationItem(position);
if (mCurrentPosition == position) {
}
mNextPosition = position;
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
From this page:
The fragment of each page the user visits will be kept in memory,
though its view hierarchy may be destroyed when not visible.
This means that your fragments that are not visible to the user are still being kept in memory, so their onCreate methods won't be called when they're redisplayed. You can force them to be kicked out of memory when you switch pages by setting the ViewPager's offscreen page limit to 0.
A better way might be to use some sort of external data model shared between your Fragments and then use your onPageSelected method to tell the Fragment to update itself based on the data model when brought into view.
when you are on a Tab:(n), only Tab:(n-1) and Tab:(n+1) will be alive in the memory, for memory usage optimization. Rest all Tabs will be destroyed, thats the reason why when you come back to the first Tab, its onCreateView is being called again.
Actually Tab:1's onCreateView will be called even if you click Tab:2 because its the neighbourhood Tab.
One solution i got is:
change the OffscreenPageLimit of the ViewPager. Its default value is 1
Try changing it to 0. Should work.But in case if it didn't
Use the Call backs
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
Is possible to use TabWidget without TabHost? I wanna something like Tabs navigation for ActionBar failback for older phones.
So I only want to show user tabs and listen on click actions, where I get active tab ID. Nothing more.
I know in common situations TabsNavigatin for actionBar is just for navigate through Fragments. But I easily avoid Fragments. :
class mTabListener implements ActionBar.TabListener {
private Screen screen;
public mTabListener(Screen screen) {
this.screen = screen;
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
screen.onTabReselected(tab, ft);
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
screen.onTabSelected(tab, ft);
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
screen.onTabUnselected(tab, ft);
}
}
public abstract class Screen extends Activity {
protected void addTab(String title, int what, boolean selected) {
if (Global.API < 11)
return;
ActionBar bar = getActionBar();
Tab tab = bar.newTab()
.setTag(new Integer(what))
.setTabListener(new mTabListener(this))
.setText(title);
bar.addTab(tab, selected);
}
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
}
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
Integer what = (Integer)tab.getTag();
tabSelected(what);
}
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
}
public void tabSelected(int what) {
}
}
But I can't find how to add tab buttons to TabWidget;
No. Tab widget without tab host is like using pushbutton for the tabs. You will have do the manipulation of tab navigation.
Here is the solution, TabWidget without tabHost
https://github.com/muratonnet/android-SingleTabWidget
I used Tab-activity in my application,but this class is depreciated now,how can I replace this with fragment.I have implemented sub tabs also for each tabs.Can any one help me by providing sample code to implement this changes?
Check out these links
http://developer.android.com/resources/samples/Support4Demos/src/com/example/android/supportv4/app/FragmentTabs.html
https://stackoverflow.com/questions/9714650/converting-tabactivity-into-fragmentactivity
The first has sample code on how to build tabs using fragments (you can pretty much use it as is), and the latter is a discussion about the same.
Use actionbar with only tabs.ActionBarSherlock library can do this very easily. Go through TabNavigationCollapsed class in samples of ActionBarSherlock.
public class TabNavigationCollapsed extends SherlockActivity implements ActionBar.TabListener {
private TextView mSelected;
#Override
public void onCreate(Bundle savedInstanceState) {
setTheme(SampleList.THEME); //Used for theme switching in samples
super.onCreate(savedInstanceState);
setContentView(R.layout.tab_navigation);
mSelected = (TextView)findViewById(R.id.text);
getSupportActionBar().setDisplayShowHomeEnabled(false);
getSupportActionBar().setDisplayShowTitleEnabled(false);
getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
for (int i = 1; i <= 3; i++) {
ActionBar.Tab tab = getSupportActionBar().newTab();
tab.setText("Tab " + i);
tab.setTabListener(this);
getSupportActionBar().addTab(tab);
}
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction transaction) {
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction transaction) {
mSelected.setText("Selected: " + tab.getText());
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction transaction) {
}
}
public class TaskDetailTabHome extends Activity implements ActionBar.TabListener{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tablayout);
ActionBar bar = getActionBar();
bar.addTab(bar.newTab().setText("TASK").setTabListener(this));
bar.addTab(bar.newTab().setText("COMMENT").setTabListener(this));
bar.addTab(bar.newTab().setText("FLIGHT").setTabListener(this));
bar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_USE_LOGO);
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayShowHomeEnabled(true);
bar.setDisplayShowTitleEnabled(false);
}
#Override
public void onTabReselected(Tab arg0, FragmentTransaction arg1) {
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
// Here what I would like to do is ...
// if (tabselect is TASK)
// Go to Task.class
// if (tabselected is COMMENT)
// Go to Comment.class
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
}
What do I do in onTabSelected method ? Do I need that Fragment ?
What do I do in onTabSelected method ?
Update your UI to reflect the selected tab. This could involve:
Using the supplied FragmentTransaction to replace a fragment
Replacing the child View of a FrameLayout
Setting the active child of a ViewFlipper
Etc.
Do I need that Fragment ?
You do not appear to have a fragment.
// Here what I would like to do is ...
// if (tabselect is TASK)
// Go to Task.class
// if (tabselected is COMMENT)
// Go to Comment.class
You do not use tabs to "go to" something. You use buttons, menus, list item clicks, etc. to "go to" another activity.
You use tabs to show something. That "something" could be implemented by other classes, if they are Fragments or are ViewGroups.