How to delete fragments related to FragmentStatePagerAdapter by deleting the parent fragment - android

I have a TabsFragment, that is used to display FragmentStatePagerAdapter. To display tabs, I firstly create a TabsFragment, which creates multiple fragments, stored in tabs. The problem is, when I destroy a TabsFragment and create a new one, tab fragments created by previous TabsFragment are kept in memory for some reason. So does look like my TabsFragment class:
public class TabsFragment extends AbstractFragment {
public static final String TAG = "Tabs_Fragment";
private ViewPagerParallax viewPager;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_tabs, container, false);
viewPager = (ViewPagerParallax)view.findViewById(R.id.viewpager);
viewPager.set_max_pages(CustomFragmentPagerAdapter.PAGE_COUNT);
viewPager.setBackgroundAsset(R.drawable.background);
viewPager.setAdapter(new CustomFragmentPagerAdapter(getFragmentManager()));
PagerSlidingTabStrip tabsStrip = (PagerSlidingTabStrip) view.findViewById(R.id.tabs);
tabsStrip.setViewPager(viewPager);
return view;
}
...
}
Like this I replace my TabsFragment with some other fragment:
public void transactOver(AbstractFragment what, int direction) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment_content, what, what.getClassTag());
ft.commit();
}
Where R.id.fragment_content is a framelayout, that stores my fragmens. CustomFragmentPagerAdapter is coded as usual.

Finished up changing
viewPager.setAdapter(new CustomFragmentPagerAdapter(getFragmentManager()));
with
viewPager.setAdapter(new CustomFragmentPagerAdapter(getChildFragmentManager()));

Related

Empty fragment when I reload it

Basically, I have a MainActivity that displays different Fragments when clicked on menu options.
Stats, is a Fragment that displays 4 fragments in it. Every time it is displayed, will replace 4 FrameLayouts on the view.
The first time work perfectly, but when I change to different fragments and get back in Stats, it seems not to replace the FrameLayouts to Fragments...
Stats as follows:
public class StatsFragment extends Fragment {
private View rootView;
private MoreSoldBarChartFragment moreSold = MoreSoldBarChartFragment.newInstance(null);
private MoreIncomeBarChartFragment moreIncome = MoreIncomeBarChartFragment.newInstance(null);
private SoldLineChartFragment soldLine = SoldLineChartFragment.newInstance(null);
private IncomeLineChartFragment incomeLine = IncomeLineChartFragment.newInstance(null);
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_stats, container, false);
initViews();
return rootView;
}
public void initViews() {
replace(moreIncome, R.id.moreIncome);
replace(moreSold, R.id.moreSold);
replace(soldLine, R.id.soldLine);
replace(incomeLine, R.id.incomeLine);
}
private void replace(Fragment fragmentToReplace, int container) {
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.replace(container, fragmentToReplace);
ft.commit();
}
public static StatsFragment newInstance(Bundle args) {
StatsFragment fragment = new StatsFragment();
fragment.setHasOptionsMenu(true);
fragment.setArguments(args);
return fragment;
}
}
You should be using getChildFragmentManager() to display Fragments within Fragments:
private void replace(Fragment fragmentToReplace, int container) {
FragmentTransaction ft = getChildFragmentManager().beginTransaction();
ft.replace(container, fragmentToReplace);
ft.commit();
}
As that ensures that the Fragments are properly handled when the parent's state is changed (i.e., when it is swapped with another Fragment and back). When you use getActivity.getSupportFragmentManager(), Fragments have no idea that these Fragments are related and can't restore the Fragments.

How can i Force a ViewPager to make their Fragments to be recreated?

Scenarios:
I have a Fragment with a ViewPager, that it has a FragmentPagerAdapter that provides 3 Fragments.
So the first time my application loads, the 3 tab fragments looks just fine.
When I navigate in the application, i do a FragmentManager.replace to load another fragment.
When i go back, or navigate to the Main View (the tabbed View) my first and second tabs are blank.
I debugged the app, and the Fragment.onDestroyView never gets call on the Tab fragment, so when it shows again, the Fragment.onCreateView never gets called again, so my view is blank.
If I navigate to the third Tab in the Tabbed Fragment, then the Fragment.onDestroy gets called by the PageAdapter (i supposed because of the 1 offLimit on the ViewPager)
So, my question is, once another Fragment is loaded in my Activity, and then i go back, or navigate to the Tabbed View, how can i force the ViewPager, or the PageAdapter, or even the Fragment itself to be recreated.
So far i try to do a FragmentManager.remove(fragment) with the TabView without any look, also, every time, i navigate to the Tabbed View i pass a new instance to the FragmentManager.replace method, it seems that every time, he pulls the same object from the FragmentManager.
TabView (Fragment):
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.tab_view, container, false);
viewPager = (ViewPager) view.findViewById(R.id.view_iam);
final PagerAdapter pagerAdapter = new MyFragmentAdapter(getActivity().getSupportFragmentManager());
viewPager.setAdapter(pagerAdapter);
return view;
}
PageAdapter:
private static class MyFragmentAdapter extends FragmentPagerAdapter {
private Fragment[] tabs;
private String[] names;
public MyFragmentAdapter(FragmentManager fm) {
super(fm);
tabs = new Fragment[]{new FlightsView(), new MyFlightsRequestView(),
new MyFlightsView()};
names = new String[]{"VUELOS", "SOLICITUDES", "MIS VUELOS"};
}
#Override
public Fragment getItem(int position) {
return tabs[position];
}
#Override
public int getCount() {
return tabs.length;
}
#Override
public String getPageTitle(int position) {
return names[position];
}
}
FlightsView (One of the Tab Fragments)
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.view_flight, container, false);
recycle_view = (RecyclerView) view.findViewById(R.id.recycler_view);
progressBar = (ProgressBar) view.findViewById(R.id.progress_bar);
setHasOptionsMenu(true);
return view;
}
Can you please try to extend your adapter from FragmentStatePagerAdapter instead of FragmentPagerAdapter

ViewPager only load the fragments once time

I have an android DrawerLayout and it has 2 items, one of them is a fragment with a PagerTabStrip and it load their fragments but when I change the item of the DrawerLayout and I come back to the PagerTabStrip it loads the tabs, but doesn't their fragments.
This is my PagerTabStrip class
public class maintabs extends Fragment {
FragmentPagerAdapter adapterViewPager;
PagerTabStrip pagerTabStrip;
View rootView;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.tabs_main, container, false);
ViewPager vpPager = (ViewPager) rootView.findViewById(R.id.vpPager);
pagerTabStrip = (PagerTabStrip) rootView.findViewById(R.id.pager_header);
pagerTabStrip.setDrawFullUnderline(true);
adapterViewPager = new SampleFragmentPagerAdapter(getFragmentManager());
vpPager.setAdapter(adapterViewPager);
return rootView;
}
}
I've found a solution.
Just use a FragmentStatePagerAdapter instead FragmentPagerAdapter

Android ViewPager Inside Fragment Loaded Only Once

I am getting issue with ViewPager. I am using FragmentActivity and I added the multiple fragment inside FragmentActivity as following method.
public void addFragment(Fragment fragment, boolean addToBackStack, int transition) {
FragmentTransaction ft = getFragmentManager().beginTransaction().setCustomAnimations(R.anim.slide_up,R.anim.slide_down,R.anim.slide_up,R.anim.slide_down);
ft.replace(R.id.main, fragment);
ft.setTransition(transition);
if (addToBackStack)
ft.addToBackStack(null);
ft.commit();
}
I am using ViewPager Inside the fragment. ViewPager is working fine when FragmentActivity loaded. but when i use another fragment ViewPager got invisible.
for example
a.) Fragment A with ViewPager
b.) Fragment B without ViewPager
Fragment A working fine when I run App. when i go to Fragment B
then I again i replace Fragment B to Fragment A then ViewPager is not working. I see the blank view where I am using ViewPager.
Please let me know How can i solve this issue
Thanks
I solved it myself the issue was when you use the ViewPager inside the fragment use getChildFragmentManager() instead of getSupportFragmentManager() or getFragmentManager().
That's it.
I cannot comment so I'm going to write an answer here.
Why you don't just put the viewpager as a fragment:
public class ViewPager extends Fragment{
public static final String TAG = ViewPager.class.getSimpleName();
private ViewPagerAdapter mAdapter;
public static ViewPager newinstance(){
ViewPager viewPager = new ViewPager();
return viewPager ;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.view_pager, container, false);
ViewPager viewPager = (ViewPager) view.findViewById(R.id.pager);
mAdapter = new ViewPagerAdapter(getChildFragmentManager());
viewPager.setAdapter(mAdapter);
return view;
}
}
In your adapter:
public class ViewPagerAdapter extends FragmentPagerAdapter{
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int arg0) {
return Fragment.newinstance();
}
#Override
public int getCount() {
return 5; //number of pages on your viewPager
}
Then on your main activity you can make the transaction to add the view pager
ViewPager viewPager = ViewPager.newInstance();
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.content_frame,viewPager);
ft.addToBackStack(ViewPager.TAG);
ft.commit();

Tab content disappeared after rotation inside ViewPager

I put a FragmentTabHost into a ViewPager, but the tab content has gone after I rotate the device. The tab content will come back if I click on another tab to refresh content. Is there anything wrong in my code? Please help me know.
public class MyActivity extends FragmentActivity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LayoutInflater inflater = getLayoutInflater();
View tabView = inflater.inflate(R.layout.tab, null);
FragmentTabHost tabHost = (FragmentTabHost) tabView.findViewById(android.R.id.tabhost);
tabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
tabHost.addTab(tabHost.newTabSpec("tab1").setIndicator("Tab1"), TabContent1Fragment.class, null);
tabHost.addTab(tabHost.newTabSpec("tab2").setIndicator("Tab2"), TabContent2Fragment.class, null);
View page2 = inflater.inflate(R.layout.page2, null);
ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager);
List<View> list = new ArrayList<View>();
list.add(page2);
list.add(tabView);
viewPager.setAdapter(new DemoPagerAdapter(list));
}
}
public class TabContent1Fragment extends Fragment
{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.tab_content_1, null);
}
}
public class DemoPagerAdapter extends PagerAdapter
{
private List<View> mModeViewPageList;
public DemoPagerAdapter(List<View> modeViewPageList)
{
this.mModeViewPageList = modeViewPageList;
}
#Override
public Object instantiateItem(ViewGroup container, int position)
{
container.addView(mModeViewPageList.get(position), 0);
return mModeViewPageList.get(position);
}
#Override
public void destroyItem(ViewGroup container, int position, Object object)
{
container.removeView(mModeViewPageList.get(position));
}
#Override
public int getCount()
{
return mModeViewPageList.size();
}
#Override
public boolean isViewFromObject(View view, Object o)
{
return view == o;
}
}
Thanks to my friend, finally I found the reason was that I used PagerAdapter.
When device is rotated, all views will be recreated. But without extra codes for fragment management, PagerAdapter is not able to mange the state of the fragments inside views (tab content fragments in realtabcontent in my case) and the child fragment of a view will disappear after rotation.
So I should change all views for ViewPager into fragments and use FragmentPagerAdapter instead.
One more thing, it should be used getChildFragmentManager() from Fragment in onCreateView instead of getSupportFragmentManger() from FragmentActivity to manage the child fragments in a fragment.
I wanted to point out an important point in Light's answer. If you convert an Activity to a Fragment then you may have been using getSupportFragmentManager. When converting it, you may have changed it to getActivity().getSupportFragmentManager(). It will seemingly work until you leave and return to the fragment, and you'll find some fragments missing until you scroll the pager.
The solution is to change getActivity().getSupportFragmentManager() to getChildFragmentManager().

Categories

Resources