简体   繁体   中英

Android TabLayout ViewPager not inflating tab fragment on backstack

I've got a tab view set up that that has custom fragments for each tab using a viewpager. This is my code:

Holding Fragment

public class FragInboxMainView extends Fragment implements CGFragment {
    private CGController controller;
    private CGFragment thisFragment;

    @Bind(R.id.inboxViewPager)ViewPager inboxViewPager;
    @Bind(R.id.inboxTabs)TabLayout inboxTabLayout;
    @Bind(R.id.inbox_progress_wheel)ProgressWheel inboxProgressWheel;

    public FragInboxMainView(){}

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.fragment_inbox_mainview, container, false);
        ButterKnife.bind(this, rootView);
        thisFragment = this;
        Globals g = Globals.getInstance();
        /** Show loading spinner */
        this.inboxProgressWheel.setBarColor(ContextCompat.getColor(controller.getContext(), g.getUserObject().getUserThemeColor()));
        this.inboxProgressWheel.setVisibility(View.VISIBLE);
        /** Display the profile information based off the ID */
        controller.displayInbox(thisFragment);

        return rootView;
    }


    public void hideProgressSpinner() {
        this.inboxProgressWheel.setVisibility(View.GONE);
    }


    public ViewPager getInboxViewPager() {
        return this.inboxViewPager;
    }

    public TabLayout getInboxTabLayout() {
        return this.inboxTabLayout;
    }
}

Its layout file

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:app="http://schemas.android.com/apk/res-auto"
              xmlns:wheel="http://schemas.android.com/apk/res-auto"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">
    <android.support.design.widget.TabLayout
        android:id="@+id/inboxTabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMode="scrollable" />
    <com.pnikosis.materialishprogress.ProgressWheel
        android:id="@+id/inbox_progress_wheel"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:layout_gravity="center"
        wheel:matProg_barColor="#5588FF"
        wheel:matProg_progressIndeterminate="true"
        android:visibility="gone"/>


    <android.support.v4.view.ViewPager
        android:id="@+id/inboxViewPager"
        android:layout_width="match_parent"
        android:layout_height="0px"
        android:layout_weight="1"
        android:background="@android:color/white" />
</LinearLayout>

Tab fragment and its inflation file

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    android:id="@+id/main_content"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.baoyz.widget.PullRefreshLayout
        android:id="@+id/tabPullRefresh"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    <view
        android:id="@+id/tabRecyclerHolder"
        class="android.support.v7.widget.RecyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingTop="8dp"
        android:paddingBottom="8dp"
        android:clipToPadding="false"
        android:layout_centerInParent="true"/>

    </com.baoyz.widget.PullRefreshLayout>
    <com.melnykov.fab.FloatingActionButton
        android:id="@+id/tabFab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|right"
        android:layout_margin="16dp"
        android:src="@mipmap/ic_add_white"/>
</android.support.design.widget.CoordinatorLayout>

public class TabRecyclerHolder extends Fragment {

    @Bind(R.id.tabRecyclerHolder) RecyclerView tabRecyclerHolder;
    @Bind(R.id.tabPullRefresh) PullRefreshLayout tabPullRefresh;
    @Bind(R.id.tabFab) FloatingActionButton recyclerFab;

    private String tabTitle = "Title";


    public TabRecyclerHolder(){}

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.tab_recycler_holder, container, false);

        ButterKnife.bind(this, rootView);

        recyclerFab.hide(false);

        tabPullRefresh.setRefreshStyle(PullRefreshLayout.STYLE_MATERIAL);

        return rootView;
    }

    public RecyclerView getTabRecyclerHolder() {
        return this.tabRecyclerHolder;
    }

    public FloatingActionButton getRecyclerFab() {
        return this.recyclerFab;
    }

    public String getTabTitle() {
        return this.tabTitle;
    }

    public void setTabTitle(String title) {
        this.tabTitle = title;
    }

    public PullRefreshLayout getTabPullRefresh() {
        return this.tabPullRefresh;
    }
}

My tab adapter

public class TabPagerAdapter extends FragmentStatePagerAdapter {

    private CGController controller;
    private List<Object> items;

    public TabPagerAdapter(FragmentManager fm, CGController controller, List<Object> items) {
        super(fm);
        this.controller = controller;
        this.items = items;
    }

    @Override
    public int getCount() {
        return items.size();
    }

    @Override
    public Fragment getItem(int num) {
        return (TabRecyclerHolder)items.get(num);
    }

    @Override
    public String getPageTitle(int num){
        return ((TabRecyclerHolder)items.get(num)).getTabTitle();
    }
}

The processing code

public void viewInbox() {
    /** Set up the views */
    receivedHolder = new TabRecyclerHolder();
    receivedHolder.setTabTitle(Constants.TAB_INBOX_RECEIVED);
    sentHolder = new TabRecyclerHolder();
    sentHolder.setTabTitle(Constants.TAB_INBOX_SENT);

    tabs.add(receivedHolder);
    tabs.add(sentHolder);

    /** Set up the tabs */
    final ViewPager inboxViewPager = inboxFragment.getInboxViewPager();
    TabLayout inboxTabLayout = inboxFragment.getInboxTabLayout();

    /** Set the adapter for the view pager */
    inboxViewPager.setAdapter(new TabPagerAdapter(inboxFragment.getChildFragmentManager(), controller, tabs));
    /** set up the tab look and feel */
    inboxTabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
    inboxTabLayout.setTabMode(TabLayout.MODE_FIXED);

    inboxViewPager.setOffscreenPageLimit(3);
    inboxViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(inboxTabLayout));
    inboxTabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            inboxViewPager.setCurrentItem(tab.getPosition());
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    });

    /** And, display! */
    inboxTabLayout.setupWithViewPager(inboxViewPager);

    receivedAdapter = new RecyclerListAdapter(controller, items);
    final RecyclerView receivedList = receivedHolder.getTabRecyclerHolder();
    receivedList.setLayoutManager(new LinearLayoutManager(controller.getContext()));
    receivedList.setAdapter(receivedAdapter);
}

There is some code i've missed out but its not pertanent to the question. The code works perfectly when initially viewing the fragment. However since my application contains a single activity and just replaces a content view for each fragment navigated to, each fragment is added to the back stack and then popped when the back button is pressed. My issue is that when navigating back to this fragment the view inside the tab isn't being inflated, which means that no elements can be accessed (and therefore the app crashes while trying to display the data in the recyclerview etc).

I have had a look at this question: TabLayout ViewPager Not Loading When Using Backstack and implemented its suggestion (using getChildFragmentManager() when setting up the pager adapter) however that has not fixed my issue.

Help would be appreciated!

Change this public View onCreateView(LayoutInflater inflater,... to public void onViewCreated (View view, Bundle savedInstanceState)

so you are going to have something like this

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {        
    return inflater.inflate(R.layout.tab_recycler_holder, container, false);
}

then

@Override
public void onViewCreated (View view, Bundle savedInstanceState){
     ButterKnife.bind(this, view);
    recyclerFab.hide(false);
    tabPullRefresh.setRefreshStyle(PullRefreshLayout.STYLE_MATERIAL);
    ...

see if it helps

将 TabPagerAdapter 中的 FragmentStatePagerAdapter 扩展为

FragmentStatePagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT)

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