Using unknown number of tabs - android

I want to create an activity that can display any number of tabs, without creating an activity for each tab.
Is it possible?
The only way I saw creating tabs included creating an activity for each one.

You can try as follows ,
Extend your activity from ActionBarActivity and add required number of tabs programmatically ,
ActionBar.TabListener tabListener;
mactionBar = getActionBar();
mactionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
tabListener=new ActionBar.TabListener() {
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
displayTabs(tab.getPosition());
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
displayTabs(tab.getPosition());
}
};
mactionBar.addTab(mactionBar.newTab().setText(<any text>).setTabListener(tabListener));
//call the same method for required number of tabs
Call the same fragment for each tab click
private void displayTabs(int position)
{
Fragment fragment = null;
switch (position) {
case 0:
fragment = new YourFragment();
break;
case 1:
fragment = new YourFragment();
break;
// same for required numder of cases
default:
break;
}
if (fragment != null)
{
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(<container id>, fragment).commit();
}
}

Related

Switching back in tabs

I have three tabs with a pageviewer and actionbar bar. When I try to switch back to a tab that was already selected, no data is shown, but the logcat indicates that data was pulled from the server and add in the arraylist.
Any suggestions as to why the data will not show now? I have done extensive research and still fail to understand what is happening.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_tabs);
viewPager = (ViewPager) findViewById(R.id.pager);
Log.v("Main-onCreate-viewPager", viewPager.toString());
actionBar = getSupportActionBar();
mAdapter = new TabsPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(mAdapter);
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Adding Tabs
for (String tab_name : tabs) {
actionBar.addTab(actionBar.newTab().setText(tab_name).setTabListener(this));
Log.v("Main", "tab added");
}
/**
* on swiping the viewpager make respective tab selected
**/
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
Log.v("onPageScrolled-position", Integer.toString(position));
Log.v("onPageScrolled-position", Float.toString(positionOffset));
Log.v("onPageScrolled-position", Integer.toString(positionOffsetPixels));
}
public void onPageSelected(int position) {
// on changing the page
// make respected tab selected
Log.v("onPageSelected", "onPageSelected");
actionBar.setSelectedNavigationItem(position);
Log.v("onPageSelected-position", Integer.toString(position));
}
public void onPageScrollStateChanged(int state) {
Log.v("StateChanged", "OnPageScrollStateChanged");
Log.v("statechanged-state", Integer.toString(state));
}
});
}
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
Log.v("Main", "Tab REselected");
Log.v("onTabReselected", tab.toString());
Log.v("onTabReselected", ft.toString());
if(tab.getPosition() == 0){
Log.v("onTabReselected", "ImagesFragment");
Fragment frag;
FragmentManager fm1 = Main.this.getSupportFragmentManager();
FragmentTransaction ft1 = fm1.beginTransaction();
frag = new ImagesFragment();
//frag = new FeaturesFragment();
ft1.replace(R.id.pager, frag);
ft1.commit();
frag.setUserVisibleHint(true);
}
if (tab.getPosition() == 1) {
Log.v("onTabReselected", "FeaturesFragment");
Fragment frag;
FragmentManager fm1 = Main.this.getSupportFragmentManager();
FragmentTransaction ft1 = fm1.beginTransaction();
frag = new FeaturesFragment();
ft1.replace(R.id.pager, frag);
ft1.commit();
frag.setUserVisibleHint(true);
}
if (tab.getPosition() == 2) {
Log.v("onTabReselected", "OptionsFragment");
Fragment frag;
FragmentManager fm1 = Main.this.getSupportFragmentManager();
FragmentTransaction ft1 = fm1.beginTransaction();
frag = new OptionsFragment();
ft1.replace(R.id.pager, frag);
ft1.commit();
frag.setUserVisibleHint(true);
}
}
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
// on tab selected
// show respected fragment view
Log.v("onTabSelected", tab.toString());
Log.v("onTabSelected", ft.toString());
Log.v("tab position1", Integer.toString(tab.getPosition()));
viewPager.setOffscreenPageLimit(0);
//viewPager.setCurrentItem(tab.getPosition()); //null pointer exception here
tab.select(); //no null pointer exception, but no show data when swiping tabs
Log.v("onTabSelected", tab.toString());
Log.v("tab position", Integer.toString(tab.getPosition()));
if (tab.getPosition() == 0) {
Fragment frag;
FragmentManager fm1 = Main.this.getSupportFragmentManager();
FragmentTransaction ft1 = fm1.beginTransaction();
frag = new ImagesFragment();
ft1.replace(R.id.pager, frag);
ft1.commit();
frag.setUserVisibleHint(true);
}
if (tab.getPosition() == 1) {
Fragment frag;
FragmentManager fm1 = Main.this.getSupportFragmentManager();
FragmentTransaction ft1 = fm1.beginTransaction();
frag = new FeaturesFragment();
ft1.replace(R.id.pager, frag);
ft1.commit();
frag.setUserVisibleHint(true);
}
if (tab.getPosition() == 2) {
Fragment frag;
FragmentManager fm1 = Main.this.getSupportFragmentManager();
FragmentTransaction ft1 = fm1.beginTransaction();
frag = new OptionsFragment();
ft1.replace(R.id.pager, frag);
ft1.commit();
frag.setUserVisibleHint(true);
}
}
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
Log.v("Main", "Tab UNselected");
Log.v("onTabUnselected", tab.toString());
Log.v("onTabUnselected", ft.toString());
}
public class TabsPagerAdapter extends FragmentStatePagerAdapter {
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int index) {
Log.v("index", Integer.toString(index));
switch (index) {
case 0:
Log.v("TabsPagerAdapter", "case 0: ImagesFragment");
return new ImagesFragment();
case 1:
Log.v("TabsPagerAdapter", "case 1: FeaturesFragment");
return new FeaturesFragment();
case 2:
Log.v("TabsPagerAdapter", "case 2: OptionsFragment");
return new OptionsFragment();
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 3;
}
}
Use FragmentStatePagerAdapter in place of TabsPagerAdapter.
This may help you i also had this problem i have 4 tabs and switching them re creates the view, after setting adapter use this code,
viewPager.setAdapter(mAdapter);
viewPager.setOffscreenPageLimit(5); //this one.!
Any number of limit you can have but better to have low numbers because of memory customization, use it inside oncreate() method(if Activity).

How to attach existing fragment

How can I attach existing fragment, when change back tab in ActionBar.NAVIGATION_MODE_TABS?
class MyTabsListener implements ActionBar.TabListener {
public Fragment fragment;
public MyTabsListener(Fragment fragment) {
this.fragment = fragment;
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
ft.replace(R.id.fragment_container, fragment);
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
ft.detach(fragment);
}
}
You can verify if your fragment was loaded previously in the fragment stack. Also could store all your used fragments to reuse it
public void setFragment(Fragment fragmentInstance) {
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
Fragment oldFragmentInstance = fragmentManager
.findFragmentById(R.id.curr_fragment);
boolean onlyAttach = false;
List<Fragment> prevFragments = getSupportFragmentManager()
.getFragments();
for (Fragment fragment : prevFragments) {
if (fragment == null) {
continue;
}
if (fragment.getClass().equals(fragmentInstance.getClass())) {
onlyAttach = true;
fragmentInstance = fragment;
break;
}
}
fragmentTransaction.detach(oldFragmentInstance);
if (onlyAttach) {
fragmentTransaction.attach(fragmentInstance);
} else {
fragmentTransaction.replace(R.id.curr_fragment,
fragmentInstance);
fragmentTransaction.addToBackStack(null);
}
try {
fragmentTransaction.commit();
}
}
Hope this helps

android fragment replacing and removing

i have the following activity which produced 3 tabs, and put fragment in each one of them.
public class ClientActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_client);
ActionBar bar = getActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.Tab tabA = bar.newTab().setCustomView(R.layout.tab_a_layout);
ActionBar.Tab tabB = bar.newTab().setCustomView(R.layout.tab_b_layout);
ActionBar.Tab tabC = bar.newTab().setCustomView(R.layout.tab_c_layout);
Fragment fragmentA = new firstTab();
Fragment fragmentB = new secondTab();
Fragment fragmentC = new thirdTab();
tabA.setTabListener(new MyTabsListener(fragmentA));
tabB.setTabListener(new MyTabsListener(fragmentB));
tabC.setTabListener(new MyTabsListener(fragmentC));
bar.addTab(tabA);
bar.addTab(tabB);
bar.addTab(tabC);
}
protected class MyTabsListener implements ActionBar.TabListener {
private Fragment fragment;
public MyTabsListener(Fragment fragment)
{
this.fragment = fragment;
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft)
{
ft.add(R.id.fragment_place, fragment, null);
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
ft.remove(fragment);
}
}
}
in the first fragment (tabA) i have listview and listener which replacing the fragment on click.
when i am clicking on the second tab (after selecting line on the listview on tabA), the listener adding the tab instead of replacing it.
it happens because the TabUnsellected is removing the wrong fragment (it was first_tab, but replaced to test_tab on the listview selecting row).
how can i use the remove option on the ft on TabUnselected to remove the CURRENT fragment on the tab, assuming i have always 1 fragment on each tab?
Thanks
Fixed it by changing from ft.add to ft.replace on the TabSelected:
ft = getFragmentManager().beginTransaction();
ft.replace(R.id.fragment_place, fragment);
ft.commit();

How to change Actionbar Tab from fragment

i have 3 actionbar tabs home:video:purchase by default home will be selected.I can switch between different tabs where i'm able to replace the fragments.I have a gridview in home fragment on click of any grid cell i'm using the below piece of code to navigate to purchase tab,i'm able to replace the home fragment with purchase fragment but how can change the actionbar tab from home tab to purchase tab?????
FragmentTransaction ft = parentActivity
.getFragmentManager()
.beginTransaction();
ft.replace(R.id.mainLayout,new purchase());
ft.commit();
class MyTabsListener implements ActionBar.TabListener {
public Fragment fragment;
public MyTabsListener(Fragment fragment) {
this.fragment = fragment;
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
if (fragment != null) {
ft.setCustomAnimations(R.animator.fragmentanimatorleft,
R.animator.fragmentanimatorright);
ft.replace(R.id.mainLayout, fragment);
// isSettingClicked = false;
}
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
if (fragment != null) {
try {
ft.remove(fragment);
} catch (Exception e) {
// TODO: handle exception
}
}
}

Fragment is re created when ActionbarSherlock tab is selected

I have a Fragment Activity which holds three fragments.
public class MainActivity extends SherlockFragmentActivity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActionBar bar = getSupportActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.Tab tab1 = bar.newTab();
ActionBar.Tab tab2 = bar.newTab();
ActionBar.Tab tab3 = bar.newTab();
tab1.setText("");
tab1.setIcon(R.drawable.abs__ic_menu_share_holo_dark);
tab2.setText("");
tab2.setIcon(R.drawable.abs__ic_voice_search);
tab3.setText("");
tab3.setIcon(R.drawable.abs__ic_cab_done_holo_dark);
if (savedInstanceState == null) {
tab1.setTabListener(new MyTabListener());
tab2.setTabListener(new MyTabListener());
tab3.setTabListener(new MyTabListener());
bar.addTab(tab1);
bar.addTab(tab2);
bar.addTab(tab3);
}
}
private class MyTabListener implements ActionBar.TabListener {
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
switch (tab.getPosition()) {
case 0:
FeedsActivity frag = new FeedsActivity();
ft.replace(android.R.id.content, frag);
return;
case 1:
ProfileActivity frag2 = new ProfileActivity();
ft.replace(android.R.id.content, frag2);
return;
case 2:
MyMemoirsActivity frag3 = new MyMemoirsActivity();
ft.replace(android.R.id.content, frag3);
return;
}
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
}
}
And here is first Fragment,
public class FeedsActivity extends SherlockFragment {
public static String[] MainCategory;
public static String[] MainCategoryId;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup group,
Bundle saved) {
setRetainInstance(true);
return inflater.inflate(R.layout.activity_feeds, group, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
new GetMainCategory(getActivity()).execute();
}
}
When I select second tab and then select first tab the async task in first fragment is called again.How can I retain state of first fragment so that its view is created once? I have used setRetainInstance(true) but didnt work.
I solved this issue by using show and hide instead of attach and detach.
private class MyTabListener implements ActionBar.TabListener {
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
switch (tab.getPosition()) {
case 0:
if (frag1 == null) {
// If not, instantiate and add it to the activity
frag1 = Fragment.instantiate(getApplicationContext(),
FeedsActivity.class.getName());
ft.add(android.R.id.content, frag1, "Feeds");
} else {
// If it exists, simply attach it in order to show it
ft.show(frag1);
}
return;
case 1:
if (frag2 == null) {
// If not, instantiate and add it to the activity
frag2 = Fragment.instantiate(getApplicationContext(),
ProfileActivity.class.getName());
ft.add(android.R.id.content, frag2, "Profile");
} else {
// If it exists, simply attach it in order to show it
ft.show(frag2);
}
return;
case 2:
if (frag3 == null) {
// If not, instantiate and add it to the activity
frag3 = Fragment.instantiate(getApplicationContext(),
History.class.getName());
ft.add(android.R.id.content, frag3, "History");
} else {
// If it exists, simply attach it in order to show it
ft.show(frag3);
}
return;
}
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
if (frag1 != null) {
// Detach the fragment, because another one is being attached
switch (tab.getPosition()) {
case 0:
ft.hide(frag1);
return;
case 1:
ft.hide(frag2);
return;
case 2:
ft.hide(frag3);
return;
}
}
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
}
The proper way to use TabListener is this :
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
// Check if the fragment is already initialized
if (mFragment == null) {
// If not, instantiate and add it to the activity
mFragment = Fragment.instantiate(mActivity, mClass.getName());
ft.add(android.R.id.content, mFragment, mTag);
} else {
// If it exists, simply attach it in order to show it
ft.attach(mFragment);
}
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
if (mFragment != null) {
// Detach the fragment, because another one is being attached
ft.detach(mFragment);
}
}
#override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// User selected the already selected tab. Usually do nothing.
}
Basically you need to check if that's the first time when your Fragment is being initialised. If not, you should add it to your screen and when the user unselect a tab you should detach the current visible fragment and add the new one. That's the way it should work. You don't need to create a new instance of Fragment everytime user click the tab.

Categories

Resources