简体   繁体   中英

Blank Fragment inside Tablayout / Viewpager

So i'm desperately looking for an answer to my problem. I spend hours try and retry some things but that did not work. So here is my problem :

I have only one activity for my application which is the main activity. This activity contains a bottom navigation bar and a frame layout to load a fragment depending the choice of the item on the bottom navigation bar.

My PredictionsFragment (loaded by bottom navigation bar) contains a TabLayout (using SmartTabLayout library). In this Fragment, a list of data is loaded in a thread because it use internet connection. TabLayout is containing PredictionsViewFragment which displays a RecyclerView. When I select the PredictionsFragment on my bottom navigation bar, tablayout and all the recyclerview are perfectly displayed. But when I go to another item and go back to PredictionsFragment it displays a blank view...

PredictionsFragment code :

public class PredictionsFragment extends Fragment {

    private static List<Country> countryList = new ArrayList<>();
    private ViewPager viewPager;
    private SmartTabLayout viewPagerTab;
    private FragmentStatePagerItemAdapter adapter;
    private FragmentPagerItems pages;
    private ProgressBar progressBar;
    private ViewGroup tab;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_predictions_tab, container, false);
        initView(view);
        return view;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        if (countryList.size() == 0) {
            refresh();
        } else {
            refreshViewPager();
        }
    }

    private void initView(View view) {
        tab = (ViewGroup) view.findViewById(R.id.tab);
        tab.addView(LayoutInflater.from(getContext()).inflate(R.layout.fragment_view_predictions, tab, false));
        progressBar = (ProgressBar) view.findViewById(R.id.progressbar);
        viewPager = (ViewPager) view.findViewById(R.id.viewpager);
        viewPagerTab = (SmartTabLayout) view.findViewById(R.id.viewpagertab);

        viewPager.setOffscreenPageLimit(countryList.size());

        pages = new FragmentPagerItems(getContext());
        adapter = new FragmentStatePagerItemAdapter(getFragmentManager(), pages){
            public int getItemPosition(Object object) {
                return POSITION_NONE;
            }
        };
        viewPager.setAdapter(adapter);
        viewPagerTab.setViewPager(viewPager);
    }

    private void refresh() {
        // Thread car connexion internet
        new Thread(new Runnable() {
            @Override
            public void run() {
                countryList = InternetData.getCountryList();
                refreshViewPager();
            }
        }).start();
    }


    private void refreshViewPager() {
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
            for (Country country : countryList) {
                pages.add(FragmentPagerItem.of(country.getCode(), PredictionsViewFragment.class));
            }
            adapter.notifyDataSetChanged();
            viewPagerTab.setViewPager(viewPager);
            progressBar.setVisibility(View.GONE);
            }
        });
    }

    public static List<Prediction> getPredictionList(int index) {
        return countryList.get(index).getPredictionList();
    }
}

PredictionsViewFragment code :

public class PredictionsViewFragment extends Fragment {
    private RecyclerView recyclerView;
    private PredictionAdapter adapter;
    private int position;

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.recycler_view_pronos, container, false);
        position = FragmentPagerItem.getPosition(getArguments());
        initRecyclerView(view);
        return view;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
    }

    private void initRecyclerView(View view) {
        recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
        recyclerView.setHasFixedSize(true);
        adapter = new PredictionAdapter(PredictionsFragment.getPredictionList(position));
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        recyclerView.setAdapter(adapter);
    }
}

Screenshot of the blank fragment and the app

EDIT :

When I use getChildFragmentManager() method :

adapter = new FragmentStatePagerItemAdapter(getChildFragmentManager(), pages){
            public int getItemPosition(Object object) {
                return POSITION_NONE;
            }
        };

I get this error when I go the second time on the Fragment (The first time I go on it, it works perfectly) :

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.util.SparseArray.get(int)' on a null object reference
                      at android.support.v4.app.FragmentManagerImpl.getFragment(FragmentManager.java:936)
                      at android.support.v4.app.FragmentStatePagerAdapter.restoreState(FragmentStatePagerAdapter.java:217)
                      at android.support.v4.view.ViewPager.onRestoreInstanceState(ViewPager.java:1461)
                      at android.view.View.dispatchRestoreInstanceState(View.java:18608)
                      at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3821)
                      at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3827)
                      at android.view.View.restoreHierarchyState(View.java:18586)
                      at android.support.v4.app.Fragment.restoreViewState(Fragment.java:494)
                      at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1486)
                      at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
                      at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)
                      at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:802)
                      at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2625)
                      at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2411)
                      at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2366)
                      at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2273)
                      at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:733)
                      at android.os.Handler.handleCallback(Handler.java:873)
                      at android.os.Handler.dispatchMessage(Handler.java:99)
                      at android.os.Looper.loop(Looper.java:193)
                      at android.app.ActivityThread.main(ActivityThread.java:6669)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

EDIT 2 :

I added these lines to the onViewCreated method on my PredictionsFragment :

else {
      refreshViewPager();
     }

But it does absolutely nothing... The name of the tab appears properly but not the recyclerview... It's like the Fragment inside the tablayout isn't loaded

EDIT 3 : I have added a SwipeRefreshLayout to my recyclerview and for the 2 first tabs i can't do a pull to refresh and from the 3rd tabs only one item of the recyclerview appears and pull to refresh "works" but it displays only one item in the recyclerview

If you have any questions tell me I'll do my best to answer it ! Thanks in advance for you help I appreciate it

Use setOffsetScreenPageLimit in viewPager: This will help you to store the data in the pagers fragments when you navigate through bottom tabs.

viewPager.setOffscreenPageLimit(the number of tab you are setting);
  1. For refreshing the data in recycler view you can use "Swipe refresh"

So I solved my problem...

You have to use this :

adapter = new FragmentPagerItemAdapter(getChildFragmentManager(), pages);

Use FragmentPagerItemAdapter and NOT FragmentStatePagerItemAdapter And for sur you have to use getChildFragmentManager()

I was also using BottomNavigationView to open tabLayout with viewPager & faced the same problem. FragmentStatePagerAdapter can be used for this.

This class handles saving and restoring of fragment's state -> It's in the documentation

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM