Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Viewpager does not inflate the fragments having already inflated another view pager

I have a project that needs to have two viewpager, each in a different fragment of the activity.

The architecture something like this Architecture

The problem is that when a pager view is inflated, the other isn't.

For example, the fragments 1, 2 and 3 can be accessed by clicking. When I click on the first fragment, it inflates the view pager with its two fragments perfectly, but if I click on the fragment 3, the view pager does not inflate the fragments and also the tabs get slower. Opening the application process again, by clicking on the fragment 3 first, it works perfectly, but clicking on the first after, this problem happens again.

Already debugged the processes and there is nothing different.

My Activity

public class HomeActivity extends AppCompatActivity implements NavigationFragment.OnNavigationListener{
public NavigationFragment mNavigation;

private String mTagFragmentShowing = "";
private int currentNavigation = 0;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_home);
    ButterKnife.bind(this);
    mNavigation = (NavigationFragment) getFragmentManager().findFragmentById(R.id.manager_navigation);

    onNavigationSelected(currentNavigation);
}


@Override
public void onNavigationSelected(int position) {
    if (mTagFragmentShowing.equals(String.valueOf(position)))
        return;

    currentNavigation = position;

    mNavigation.setNavigationSelected(position);
    FragmentManager fragmentManager = getSupportFragmentManager();
    Fragment fragment = fragmentManager.findFragmentByTag(mTagFragmentShowing);

    // Hide last fragment
    if (fragment != null && fragment.isVisible()) {
        fragmentManager.beginTransaction().hide(fragment).commit();
    }

    // Show new fragment
    mTagFragmentShowing = String.valueOf(position);
    fragment = fragmentManager.findFragmentByTag(mTagFragmentShowing);

    if (fragment != null && fragment.isHidden()) {
        fragmentManager.beginTransaction().show(fragment).commit();
    } else if (fragment == null) {
        fragmentManager.beginTransaction().add(R.id.manager_content, getFragmentByPosition(position), mTagFragmentShowing)
                .setTransition(FragmentTransaction.TRANSIT_NONE).commit();
    }
}

private Fragment getFragmentByPosition(int position) {
    switch (position) {
        case 0:
            return new DiscoverFragment();
        case 1:
            return new UpcomingFragment();
        case 2:
            return new FeaturesFragment();
        case 3:
            return new VideosFragment();
        case 4:
            return new MySongsFragment();
    }
    return null;
}

My Navigation Fragment. It control the other fragments

public class NavigationFragment extends Fragment implements View.OnClickListener {

public ViewHolder mHolder;
public View mButtonSelected;
public OnNavigationListener mCallback;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.component_navigation, container, false);
    ButterKnife.bind(this, view);

    initView(view);
    return view;
}

public void initView(View view) {
    mHolder = new ViewHolder();
    mHolder.discover = view.findViewById(R.id.component_navigation_discover);
    mHolder.upcoming = view.findViewById(R.id.component_navigation_upcoming);
    mHolder.features = view.findViewById(R.id.component_navigation_features);
    mHolder.videos = view.findViewById(R.id.component_navigation_videos);
    mHolder.mymusic = view.findViewById(R.id.component_navigation_mymusic);

    mHolder.discover.setTag(0);
    mHolder.upcoming.setTag(1);
    mHolder.features.setTag(2);
    mHolder.videos.setTag(3);
    mHolder.mymusic.setTag(4);

    mHolder.discover.setOnClickListener(this);
    mHolder.upcoming.setOnClickListener(this);
    mHolder.features.setOnClickListener(this);
    mHolder.videos.setOnClickListener(this);
    mHolder.mymusic.setOnClickListener(this);
    mButtonSelected = mHolder.features;
}

public void setNavigationSelected(int position) {
    setNavigationButtonSelected(false);
    switch (position) {
        case 0:
            mButtonSelected = mHolder.discover;
            break;
        case 1:
            mButtonSelected = mHolder.upcoming;
            break;
        case 2:
            mButtonSelected = mHolder.features;
            break;
        case 3:
            mButtonSelected = mHolder.videos;
            break;
        case 4:
            mButtonSelected = mHolder.mymusic;
            break;
    }
    setNavigationButtonSelected(true);
}

public void setNavigationButtonSelected(boolean enabled) {
    mButtonSelected.setBackgroundColor(enabled ? getResources().getColor(R.color.color_red) : Color.TRANSPARENT);
}

@Override
public void onClick(View view) {
    if (view != mButtonSelected) {
        mCallback.onNavigationSelected((Integer) view.getTag());
    }
}

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);

    try {
        mCallback = (OnNavigationListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString()
                + " must implement OnNavigationSelectedListener");
    }
}

@Override
public void onDetach() {
    super.onDetach();
    mCallback = null;
}

static class ViewHolder {
    View discover;
    View upcoming;
    View features;
    View videos;
    View mymusic;
}

public interface OnNavigationListener {
    public void onNavigationSelected(int position);
}

My Fragments with View Pager

public class MySongsFragment extends Fragment {
private OnFragmentInteractionListener mListener;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    getActivity().getSupportFragmentManager().beginTransaction().add(R.id.mysongs_fragment_container, MySongsViewPagerFragment.newInstance(0)).commit();

    return inflater.inflate(R.layout.fragment_my_songs, container, false);
}


@Override
public void onDetach() {
    super.onDetach();
    mListener = null;
}

/**
 * This interface must be implemented by activities that contain this
 * fragment to allow an interaction in this fragment to be communicated
 * to the activity and potentially other fragments contained in that
 * activity.
 * <p/>
 * See the Android Training lesson <a href=
 * "http://developer.android.com/training/basics/fragments/communicating.html"
 * >Communicating with Other Fragments</a> for more information.
 */
public interface OnFragmentInteractionListener {
    // TODO: Update argument type and name
    public void onFragmentInteraction(Uri uri);
}

My View Pager

public class MySongsViewPagerFragment extends Fragment {

private static final int NUM_PAGES = 4;
private String[] tab_names;
private List<String> mTabNames;
private PagerAdapter mPagerAdapter;

public @Bind(R.id.pager)
ViewPager mPager;

public static MySongsViewPagerFragment newInstance(int index) {
    MySongsViewPagerFragment fragment = new MySongsViewPagerFragment();
    Bundle args = new Bundle();
    args.putInt("index", index);
    fragment.setArguments(args);
    return fragment;
}

@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = initView(inflater, container);
    return view;
}

@NonNull private View initView(LayoutInflater inflater, ViewGroup container) {
    View view = inflater.inflate(R.layout.fragment_view_pager_my_songs, container, false);
    ButterKnife.bind(this, view);

    tab_names = getResources().getStringArray(R.array.tabs_mysongs);
    mTabNames = Arrays.asList(tab_names);

    mPagerAdapter = new ScreenSlidePagerAdapter(getActivity().getSupportFragmentManager());
    mPager.setAdapter(mPagerAdapter);

    mPager.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            mPager.onTouchEvent(event);
            return false;
        }
    });

    TabLayout tabLayout = (TabLayout) view.findViewById(R.id.tabs);
    tabLayout.setupWithViewPager(mPager);
    return view;
}



private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
    public ScreenSlidePagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override public Fragment getItem(int position) {
        switch (position) {
            case 0:
                return new PlaylistsFragment();
            case 1:
                return new SongsFragment();
            case 2:
                return new AlbumsFragment();
            case 3:
                return new ArtistsFragment();
            default:
                return new PlaylistsFragment();
        }
    }

    @Override public int getCount() {
        return NUM_PAGES;
    }

    @Override public CharSequence getPageTitle(int position) {
        return mTabNames.get(position);
    }
}
like image 597
André Dantas Avatar asked Feb 09 '23 02:02

André Dantas


1 Answers

The problem was activity context in viewpager

In My View Pagers. I change

mPagerAdapter = new ScreenSlidePagerAdapter(getActivity().getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);

to

mPagerAdapter = new ScreenSlidePagerAdapter(getChildFragmentManager());
mPager.setAdapter(mPagerAdapter);

The two viewpager used the same context. So when I inflated the first, the other was not inflated because interpreted that already existed an inflated viewpager.

Thanks for the help mcwise for show me the method getChildFragmentManager().

like image 124
André Dantas Avatar answered Feb 11 '23 00:02

André Dantas