how can i solve android tab layout switching - android

i am developing an android app which has four fragments with tablayout and each fragment has connection error dialog box.
first problem is,when i start my app,four fragments work
simultaneously at the same time.So,when i occur connection error four
dialog boxes are shown in first fragment When i switch to second tab
it doesn't show his dialog box because his dialog is shown in first
fragment.
second problem is,i create that fragments with swipe refresh layout
to fetch data from server.I call onRefresh method in onCreate method.
when i start my app,first fragment data is loaded from server but
when i switch first tab to second tab,it is not loaded his data from
server but when i switch first tab to third tab,it is work.
Also,when i switch second tab to third tab,it is not loaded data from
server but when i switch second tab to fourth tab,it is work. It is
only work when i switch tabs with one tab differ. Is there anyway to
solve that problems.
I searched this problems from internet but i didn't get my problems answer.
Please anyone help me.Thanks in advance.....
Sorry for my poor english
this is tablyout code
viewPager = (ViewPager) findViewById(R.id.viewpagerMain);
tabLayout = (TabLayout) findViewById(R.id.tablayoutMain);
tabLayout.addTab(tabLayout.newTab().setText("Noticeboard"));
tabLayout.addTab(tabLayout.newTab().setText("News"));
tabLayout.addTab(tabLayout.newTab().setText("Events"));
tabLayout.addTab(tabLayout.newTab().setText("Result"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
viewPager.setAdapter(new MyAdapter(getSupportFragmentManager(), tabLayout.getTabCount()));
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
viewPager.setOffscreenPageLimit(0);
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
This is MyAdapter class
class MyAdapter extends FragmentStatePagerAdapter {
int num_of_tab;
public MyAdapter(FragmentManager fm, int num_of_tab) {
super(fm);
this.num_of_tab = num_of_tab;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
NoticeBoardFragment noticeBoardFragment = new NoticeBoardFragment();
return noticeBoardFragment;
case 1:
NewsFragment newsFragment = new NewsFragment();
return newsFragment;
case 2:
EventsFragment eventsFragment = new EventsFragment();
return eventsFragment;
case 3:
ResultFragment resultFragment = new ResultFragment();
return resultFragment;
default:
return null;
}
}
#Override
public int getCount() {
return num_of_tab;
}
}

Override setUserVisibleHint in each fragment and write your dialog box code in if(isVisibleToUser) instead of Oncreate. This should solve your problem
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if(isVisibleToUser) {
//dialog box code here
}
}

Related

conflict between fragments inside a viewpager

whenever i swipe to move to the next fragment the code inside another fragment gets executed tho the layout is loaded properly and the code also but it also executes the code of another fragment
ex: 3 fragments A,b,c
when i swipe from fragment A to fragment b : fragment b layout and code are executed but also fragment c code
when i swipe from b to c , only the code and layout of fragment c ,so its executed properly
so the problem is if it isnt the last fragment it calls the code of next one
here is my main_activty code
public class Main2Activity extends AppCompatActivity {
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
home h1 = new home();
return h1;
case 1:
status st = new status();
return st;
case 2:
info info = new info();
return info;
case 3:
setting set = new setting();
return set;
}
return null;
}
#Override
public int getCount() {
return 4;
}
}
}
Your SectionsPagerAdapter is extending FragmentStatePagerAdapter, and its default behaviour is to preload at least one page for optimisation reasons. You can set the number of fragments it preloads using setOffscreenPageLimit but it has to be at least one.
You can use this method in your fragment and put in there something that you want executed only once the fragment becomes visible:
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
}
}

how to replace fragments on tab?

I have an activity with 2 tabs. What im trying to do is to replace between 2 fragments when each tab is pressesd. I also have 2 fragments: fragmentOne and fragmentTwo.When tab one is pressed i want to show fragmentOne and when tab two is pressed i want to show fragmentTwo.
I'm not sure if i should create a container layout in the activity and there add the fragmentOne and fragmentTwo, or maybe there is another other way to do it?
here is my code
public class InboxActivity extends AppCompatActivity {
private TabLayout tabLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_inbox);
tabLayout = (TabLayout)findViewById(R.id.tabLayout);
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
Fragment fragment;
int position = tab.getPosition();
//requests = position - 0
//invitations = position - 1
switch (position){
case 0:
break;
case 1:
break;
}
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
when case is 0 i want to show fragmentOne
when case i 1 i want to show fragmentTwo
How should i do that?
You can do it as follow:
public void onTabSelected(TabLayout.Tab tab) {
Fragment fragment = null;
switch (tab.getPosition()) {
case 0:
fragment = new FirstFragment();
break;
case 1:
fragment = new SecondFragment();
break;
}
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.simpleFrameLayout, fragment);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.commit();
}
Here is a tutorial for more information
Use a ViewPager instead.
Set an adapter in the view pager and use it with a TabLayout using
tabLayout.setupWithViewPager(viewPager);

Fragments display getting reset

I have setup a list of fragments using TabLayout and ViewPager on MainActivity as such
public class MainActivity extends AppCompatActivity implements Fragment1.OnFragmentInteractionListener, Fragment2.OnFragmentInteractionListener, Fragment3.OnFragmentInteractionListener, Fragment4.OnFragmentInteractionListener
, Fragment5.OnFragmentInteractionListener{
TabLayout tabLayout;
ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().hide();
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.viewPager);
viewPager.setAdapter(new CustomAdapater(getSupportFragmentManager(), getApplicationContext()));
tabLayout = (TabLayout) findViewById(R.id.tabLayout);
tabLayout.setupWithViewPager(viewPager);
tabLayout.setSelectedTabIndicatorColor(Color.parseColor("#51ffff"));
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
switch (tab.getPosition()) {
case 0:
tabLayout.setSelectedTabIndicatorColor(Color.parseColor("#ced21f"));
break;
case 1:
tabLayout.setSelectedTabIndicatorColor(Color.parseColor("#51ffff"));
break;
case 2:
tabLayout.setSelectedTabIndicatorColor(Color.parseColor("#FF0000"));
break;
}
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
});
}
#Override
public void onFragmentInteraction(Uri uri) {
}
private class CustomAdapater extends FragmentPagerAdapter {
private String fragments[] = {"Control", "Connection", "Log", "Others", "Others2"};
public CustomAdapater(FragmentManager supportFragmentManager, Context applicationContext) {
super(supportFragmentManager);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new Fragment1();
case 1:
return new Fragment3();
case 2:
return new Fragment2();
case 3:
return new Fragment4();
case 4:
return new Fragment5();
default:
return null;
}
}
#Override
public int getCount() {
return fragments.length;
}
#Override
public CharSequence getPageTitle(int position) {
return fragments[position];
}
}
}
Somehow when I transit from Fragment1 to Fragment3 and back to Fragment1, the views on Fragment1 gets reset to original state(Like it was just created).
This only happens if I transit 2 fragment away from the current Fragment. For example 2->4 or 3->1.
Everything is fine if the transition is next to each other, for example 2->3 or 1->2.
This is my first android app so do pardon me.
It seems like it is creating a new fragment instead loading of existing ones
Your fragment get destroyed due to the fact that by default viewpager retain only one fragment at a time while moving around so you can simply use
viewPager.setOffscreenPageLimit(no_of_fragment_to_retain);
or
viewPager.setOffscreenPageLimit(3); // in your case
so when you come back from 4->1 or 3->1 you will get the previous stored state of your fragment. link to docs
First :
viewPager.setAdapter(new CustomAdapater(getSupportFragmentManager(), getBaseContext()));
Now see : in get Item method of View pager evrytime when you go to new tab a new instance of fragment is created So the previous view is lost . You should retain state in your fragment class.
or a simple solution is use FragmentstatepagerAdapter instead of FragmentPagerAdapter in your Adapter class.
Let me know if it helps

How to solve this that tabs in viewpager overlay when screen rotation?

Here, I have a Activity with a ViewPager, it has 4 tabs, here is the activity screen shot link.
Here is the screen shot for tab 4, when the screen is vertical.
when the activity is opened, I switch to the fourth tab, and then switch to the second, rotate the screen, part of the fourth tab will overlay on the second tab, but when switch to the first and the third, it won't happen,
the picture is as following:
tab 4:
tab 1:
tab 2:
How could I have solved this problem?
following is the adapter of viewpager:
public class MainPageFragmentPageAdapter extends FragmentPagerAdapter {
SparseArray<Fragment> fragmentSparseArray = new SparseArray<Fragment>();
private Fragment currentSelectedFragment;
public MainPageFragmentPageAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
if (fragmentSparseArray.get(position) == null) {
Fragment fragment = null;
switch (position) {
case 0:
fragment = new NewHomePageFragment();
break;
case 1:
fragment = new NewDiscoverFragment();
break;
case 2:
fragment = new NewUserMessageFragment();
break;
case 3:
fragment = new NewUserDetailFragment();
}
fragmentSparseArray.put(position, fragment);
}
currentSelectedFragment = fragmentSparseArray.get(position);
return currentSelectedFragment;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
}
#Override
public int getCount() {
return 4;
}
public Fragment getCurrentSelectedFragment() {
return currentSelectedFragment;
}
}
Any code you want to see please comment below.
As you said, You do not destroyItem when pager is not visible,so it will still in memory,and redraw it
Please manage screen orientation through onConfigurationChanged Android method.

I don't want to refresh fragment on change

I have 3 fragments... with their 3 navigation tabs.
The problem is that if i'm on the first tab, and i click the third.. when I click another time the first, it reloads all the fragment. If I click the second tab (in the middle) and I click the first, it doesn't reload.
My objective is that I don't want to refresh my fragments never!
How can I do it?
My code is:
public class TabsPagerAdapter extends FragmentPagerAdapter {
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
// Return Items
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
return new Retos();
case 1:
return new Amics();
case 2:
return new Ranking();
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 3;
}
}
And this :
public class Perfil extends ActionBarActivity implements ActionBar.TabListener{
private ViewPager viewPager;
private TabsPagerAdapter mAdapter;
private ActionBar actionBar;
private SearchView mSearchView;
private TextView mStatusView;
// Tab titles
private String[] tabs = { "TAB1", "TAB2", "TAB3" };
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.perfil);
// Initilization
viewPager = (ViewPager) findViewById(R.id.pager);
actionBar = getSupportActionBar();
mAdapter = new TabsPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(mAdapter);
actionBar.setHomeButtonEnabled(true);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
/** Creating fragment1 Tab */
Tab tab = actionBar.newTab()
.setText("TAB1")
.setTabListener(this);
actionBar.addTab(tab);
/** Creating fragment2 Tab */
tab = actionBar.newTab()
.setText("TAB2")
.setTabListener(this);
//.setIcon(R.drawable.ic_action_group);
actionBar.addTab(tab);
/** Creating fragment3 Tab */
tab = actionBar.newTab()
.setText("TAB3")
.setTabListener(this);
actionBar.addTab(tab);
/**
* on swiping the viewpager make respective tab selected
* */
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// on changing the page
// make respected tab selected
actionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
// on tab selected
// show respected fragment view
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
}
viewPager.setOffscreenPageLimit(C_FRAGMENTS_TO_KEEP_IN_MEMORY);
C_FRAGMENTS_TO_KEEP_IN_MEMORY is the number of tabs at right and left of the current selected tab to keep in memory. So in your case should be 2.
Please be sure that you are NOT creating a new fragment instance each time you call the getItem method in you viewpager adapter.
Check the #Rarw answer in this page.
Try setting your ViewPager offScreenPageLimit to cover the number of fragments you are trying to load. OffScreenPageLimist keeps fragments alive in an idle state when they are not visible. I don't see that value set in your code and based on what you're describing, that fragments keep recycling, it sounds to me like you're using the default state of 1, which will only retain one of the fragments off screen and not both.
Some caveats, this approach only really works if you know in advance how many fragments you will need since if you're dynamically adding and removing fragments its hard to know how many if any to retain.
UPDATE
This is likely why you're pages are refreshing:
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
return new Retos();
case 1:
return new Amics();
case 2:
return new Ranking();
}
return null;
}
You keep returning a new fragment each time you switch id. What you should do something like this:
case 0:
if(mRetrosFragment == null)
mRetrosFragment = new Retros();
return mRetrosFragment;
This way you stop recreating the fragment every time the tab changes and instead retain that instance.

Categories

Resources