I have faced an issue where my data is not longer showing in the fragment when i navigate from one tab to another tab and then coming back to the previous tab.
These are the code for my tablayout and viewpager
tabLayout = (TabLayout) findViewById(R.id.tablayout);
Todaybooking = (TabItem) findViewById(R.id.Tab1);
Booking = (TabItem) findViewById(R.id.Tab2);
viewPager = findViewById(R.id.viewpager);
pagerAdapter = new FragmentAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(pagerAdapter);
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
if(tab.getPosition() == 0){
pagerAdapter.notifyDataSetChanged();
} else if (tab.getPosition() == 1){
pagerAdapter.notifyDataSetChanged();
}
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
These are the fragmentadapter i have created
public class FragmentAdapter extends FragmentPagerAdapter {
private int numoftabs;
public FragmentAdapter(#NonNull FragmentManager fm, int numoftabs) {
super(fm, numoftabs);
this.numoftabs = numoftabs;
}
#NonNull
#Override
public Fragment getItem(int position) {
switch(position){
case 0:
return new Todaybooking();
case 1:
return new Booking();
default:
return null;
}
}
#Override
public int getCount() {
return numoftabs;
}
#Override
public int getItemPosition(#NonNull Object object) {
return POSITION_NONE;
}
The fragment on Today's booking is not showing once i click the bookings tab and navigate back to the previous tab.
This is probably because you are returning POSITION_NONE in getItemPosition which is
Called when the host view is attempting to determine if an item's position has changed. Returns POSITION_UNCHANGED if the position of the given item has not changed or POSITION_NONE if the item is no longer present in the adapter.
from https://developer.android.com/reference/androidx/viewpager/widget/PagerAdapter#getItemPosition(java.lang.Object)
So Remove the override of getItemPosition you don't need this normally.
Because you are indicating that the current instance of each Fragment is no longer in the list of Fragments it will be cause the Fragment to be re-created each time you visit the Tab that holds it.
Related
I have a tablayout (tab1, tab2, tab3) with a ViewPager. It seems that on app startup the tab2 is preloaded which is fine.
However, I need to input some data on tab1 and I want the tab2 to update its fragment and hide some buttons based on the data input from tab1.
How to do that? Is there a way to not preload the tab so that when I swipe to tab2, it will be getting the latest data instead of the old data?
Here's my code
private ViewPager viewPager;
private PagerAdapter adapter;
private TabLayout tabLayout;
in my onCreate method within an activity.
tabLayout.addTab(tabLayout.newTab().setText("Input"));
tabLayout.addTab(tabLayout.newTab().setText("Detail"));
tabLayout.addTab(tabLayout.newTab().setText("Chart"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
viewPager = (ViewPager) findViewById(R.id.pager);
adapter = new PagerAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
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) {
}
});
Here's my pageadapater class
public class PagerAdapter extends FragmentPagerAdapter {
int mNumOfTabs;
private InputFragment inputFragment;
private DetailFragment detailFragment;
private ChartFragment chartFragment;
public PagerAdapter(FragmentManager fm, int NumOfTabs) {
super(fm);
this.mNumOfTabs = NumOfTabs;
}
#Override
public int getItemPosition(Object object) {
// TODO Auto-generated method stub
return POSITION_NONE;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
inputFragment = new InputFragment();
return inputFragment;
case 1:
detailFragment = new detailFragment();
return detailFragment;
case 2:
chartFragment = new ChartFragment();
return chartFragment;
default:
return null;
}
}
#Override
public int getCount() {
return mNumOfTabs;
}
}
on your detailfragment fragment
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
//check values on tab 1 and try to update your tab 2 views accordingly
}
}
I have a tablayout (tab1, tab2, tab3) with a ViewPager. I want to input something in tab1, and depends on the input, tab2 and tab3 will show data accordingly.
It seems every time the app start, tab1 (fragment) and tab2 (fragment) are loaded with correct data. I'm using static variable to pass data from tab1 to tab2. However, after I change some data in tab1, tab2 doesn't update itself base on the data from tab1, it shows the old data. Here are my codes
private ViewPager viewPager;
private PagerAdapter adapter;
private TabLayout tabLayout;
in my onCreate method within an activity.
tabLayout.addTab(tabLayout.newTab().setText("Input"));
tabLayout.addTab(tabLayout.newTab().setText("Detail"));
tabLayout.addTab(tabLayout.newTab().setText("Chart"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
viewPager = (ViewPager) findViewById(R.id.pager);
adapter = new PagerAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
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) {
}
});
Here's my pageadapater class
public class PagerAdapter extends FragmentPagerAdapter {
int mNumOfTabs;
private InputFragment inputFragment;
private DetailFragment detailFragment;
private ChartFragment chartFragment;
public PagerAdapter(FragmentManager fm, int NumOfTabs) {
super(fm);
this.mNumOfTabs = NumOfTabs;
}
#Override
public int getItemPosition(Object object) {
// TODO Auto-generated method stub
return POSITION_NONE;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
inputFragment = new InputFragment();
return inputFragment;
case 1:
detailFragment = new detailFragment();
return detailFragment;
case 2:
chartFragment = new ChartFragment();
return chartFragment;
default:
return null;
}
}
#Override
public int getCount() {
return mNumOfTabs;
}
}
My question is similtar to this:
Android ViewPager Inside Fragment Loaded Only Once
The difference is that its answer doesn't work for me.
I have 4 fragments. Inside one of these fragments there is a Fragment X with ViewPager that switch betwen two other fragments. The first time I load the FragmentX the ViewPager works fine. The problem is if I switch to one of the other 4 fragments, when I go back to the FragmentX the ViewPager has nothing inside.
Fragment X
...
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_campus, container, false);
TabLayout tabLayout = (TabLayout)view.findViewById(R.id.tab_layout);
tabLayout.addTab(tabLayout.newTab().setText("Mapa"));
tabLayout.addTab(tabLayout.newTab().setText("Eventos"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
vpPager = (ViewPager)view.findViewById(R.id.vpPager);
adapterViewPager = new PagerAdapter(getChildFragmentManager());
vpPager.setAdapter(adapterViewPager);
vpPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
vpPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
return view;
}
PageAdapter
public class PagerAdapter extends FragmentPagerAdapter {
private int NUM_ITEMS = 2;
public PagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
// Returns total number of pages
#Override
public int getCount() {
return NUM_ITEMS;
}
// Returns the fragment to display for that page
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return MapFragment.newInstance(0);
case 1:
return EventosFragment.newInstance(1);
default:
return null;
}
}
// Returns the page title for the top indicator
#Override
public CharSequence getPageTitle(int position) {
return "Page " + position;
}
}
MainActivity
public boolean onNavigationItemSelected(MenuItem item) {
int id = item.getItemId();
...
if (...) {
if (campusFragment == null) // the problem is not solved by commenting this condition
campusFragment = new CampusFragment(); // Fragment X
fragmentManager.beginTransaction().replace(R.id.content_frame, campusFragment).commit();
}
}
I am using ViewPager to create 3 Fragment on Activity1,
this is my viewPager adapter :
public class ViewPagerAdapter extends FragmentStatePagerAdapter {
int mNumOfTabs;
public ViewPagerAdapter(FragmentManager fm, int NumOfTabs) {
super(fm);
this.mNumOfTabs = NumOfTabs;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
Fragment1 tab1 = new Fragment1();
return tab1;
case 1:
Fragment2 tab2 = new Fragment2();
return tab2;
case 2:
Fragment3 tab3 = new Fragment3();
return tab3;
default:
return null;
}
}
#Override
public int getCount() {
return mNumOfTabs;
}
}
this is Activity :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_1);
TabLayout tab_layout = (TabLayout) findViewById(R.id.tab_layout);
tab_layout.addTab(tab_layout.newTab().setText("Frag1"));
tab_layout.addTab(tab_layout.newTab().setText("Frag2"));
tab_layout.addTab(tab_layout.newTab().setText("Frag3"));
final ViewPager view_pager = (ViewPager) findViewById(R.id.viewpager);
final ViewPagerAdapter adapter = new ViewPagerAdapter
(getSupportFragmentManager(), tab_layout.getTabCount());
view_pager.setAdapter(adapter);
view_pager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tab_layout));
tab_layout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
view_pager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
When Activity1 is open it show Fragment1 . But I want to show Fragment2 or Fragment3 instead .
How I can to do that?
Add this line after viewpager.setAdapter(adapter); :
viewPager.setCurrentItem(index);
Index is depending on you , how many fragments you have. tabLayout.getTabCount(); will return you tab count. But index is starting from 0.
If you have 3 Fragment and want to show third Fragment you must use viewPager.setCurrentItem(2);
Set current position of viewpager to your desired possition which is 2 or 3 in your case.
new Handler().post(new Runnable() {
#Override
public void run() {
mViewPager.setCurrentItem(desiredPos);
}
});
seee more
Android ViewPager setCurrentItem not working after onResume
I am using Tablayout(android.support.design.widget.TabLayout) with ViePager instantiating 4 fragments to FragmentStatePagerAdapter.
When i scroll through all the fragments are loaded perfectly.But when i select a tab randomly pre-loaded fragment(I know that view pager instantiate neighbor fragments along current fragment) is shown instead of current fragment.
[In my case when i click 3rd tab fragment in 4th position is being shown,same fragment is shown in 4th position too].
How can i correct this situation.
Thanks in advance.
Adapter
public class OrderStatusAdapter extends FragmentStatePagerAdapter {
private final List<Fragment> mFragments = new ArrayList<>();
private final List<String> mFragmentTitles = new ArrayList<>();
public OrderStatusAdapter(FragmentManager fm) {
super(fm);
}
public void addFragment(Fragment fragment, String title) {
mFragments.add(fragment);
mFragmentTitles.add(title);
}
#Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
#Override
public int getCount() {
return mFragments.size();
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitles.get(position);
}
}
ViewPager
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
if (viewPager != null) {
setupViewPager(viewPager);
if (viewPager != null) {
viewPager.setAdapter(adapter);
tabLayout = (TabLayout) findViewById(R.id.orderStatusTabs);
tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
tabLayout.setupWithViewPager(viewPager);
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) {
}
});
}
}
private void setupViewPager(ViewPager viewPager) {
OrderStatusAdapter adapter = new OrderStatusAdapter(getSupportFragmentManager());
adapter.addFragment(FailedFragment.newInstance(list1, title), "Category 1");
adapter.addFragment(FailedFragment.newInstance(list2, title), "Category 2");
adapter.addFragment(FailedFragment.newInstance(list3, title), "Category 3");
adapter.addFragment(FailedFragment.newInstance(list4, title), "Category 4");
}
It was all because of RecycleView Custom adapter whose instance is not being destroyed and so the previous data is being loaded.So i shifted the adapter inside the fragment and it does the trick.