0

I am running into an issue where I have a fragment, which contains a tab layout/view pager which handles 3 sub fragments, and when I open the main fragment the first time all the data in the sub fragments shows up properly, but when I re-open the main fragment again (clicking on a seperate listview item), the data does not get populated properly (even though it exists).

I also noticed that the only time the sub-fragment gets its data is when view paging over to the last tab, or when rotating the screen. Also, when I try to move the screen to the right using the view pager the tab indicator will get stuck mid way between the first and second tab.

What can I do to fix this issue?

Fragment Adapter

public class DetailFragmentPagerAdapter extends FragmentPagerAdapter {

    Context context;
    final int PAGE_COUNT = 3;
    private String tabTitles[] = new String[] { "Plot", "Trailers", "Reviews" };
    private Movie movie;

    public DetailFragmentPagerAdapter(FragmentManager fm, Context context, Movie movie) {
        super(fm);
        this.context = context;
        this.movie = movie;
    }

    @Override
    public Fragment getItem(int position) {
        if(position == 0){
            return PlotFragment.newInstance(movie);
        } else if (position == 1){
            return TrailerFragment.newInstance();
        } else if (position == 2){
            return ReviewFragment.newInstance();
        } else {
            Log.e("RETURNING NULL", "RETURNING NULL");
            return null;
        }
    }

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

    @Override
    public CharSequence getPageTitle(int position) {
        return tabTitles[position];
    }
}

Main Fragment

public class MovieItemDetailFragment extends Fragment implements View.OnClickListener {
    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";
    public String TAG = MovieItemDetailFragment.class.getCanonicalName();

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    private OnFragmentInteractionListener mListener;
    private View view;
    private TextView tvTitle, tvReleaseDate, tvRating;
    private ImageView ivMoviePoster;
    private Movie movie;
    private Handler handler;

    private Button btnFavorite;
    private boolean isFavorited = false;

    private View.OnClickListener mOnClickListener;

    private ViewPager viewpager;
    private TabLayout tablayout;
    private DetailFragmentPagerAdapter adapter;


    // TODO: Rename and change types and number of parameters
    public static MovieItemDetailFragment newInstance(String param1, String param2) {
        MovieItemDetailFragment fragment = new MovieItemDetailFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    public MovieItemDetailFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

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

    private void init() {
        handler = new Handler();
        this.movie = (Movie) getArguments().getSerializable("MOVIE");


        tvTitle = (TextView) view.findViewById(R.id.tvTitle);
        tvReleaseDate = (TextView) view.findViewById(R.id.tvReleaseDate);
        tvRating = (TextView) view.findViewById(R.id.tvAvgRating);
        ivMoviePoster = (ImageView) view.findViewById(R.id.ivMoviePoster);
        btnFavorite = (Button) view.findViewById(R.id.btnFavorite);
        btnFavorite.setOnClickListener(this);

        viewpager = (ViewPager) view.findViewById(R.id.pager);
        tablayout = (TabLayout) view.findViewById(R.id.sliding_tabs);

        adapter = new DetailFragmentPagerAdapter(getActivity().getSupportFragmentManager(),
                getActivity(), getMovie());

        viewpager.setAdapter(adapter);
        adapter.notifyDataSetChanged();

        tablayout.post(new Runnable() {
            @Override
            public void run() {
                tablayout.setupWithViewPager(viewpager);
            }
        });

        mOnClickListener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                isFavorited = true;
                btnFavorite.setBackground(getActivity().getResources().getDrawable(R.drawable.favorite_content_selector));
            }
        };

        setElementValues();
    }

    private void setElementValues() {
        handler.post(new Runnable() {
            @Override
            public void run() {
                tvTitle.setText(getMovie().getTitle());
                tvReleaseDate.setText(getMovie().getRelease_date());
                tvRating.setText(String.valueOf(getMovie().getVote_average()));


                Picasso.with(getActivity()).load(getMovie().getFull_poster_path()).into(ivMoviePoster);

                if (isFavorited) {
                    btnFavorite.setBackground(getActivity().getResources().getDrawable(R.drawable.favorite_content_selector));
                } else {
                    btnFavorite.setBackground(getActivity().getResources().getDrawable(R.drawable.favorite_blank_content_selector));
                }

            }
        });

    }

    // TODO: Rename method, update argument and hook method into UI event
    public void onButtonPressed(Uri uri) {
        if (mListener != null) {
            mListener.onFragmentInteraction(uri);
        }
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (OnFragmentInteractionListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

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

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btnFavorite:
                if (isFavorited) {
                    isFavorited = false;
                    btnFavorite.setBackground(getActivity().getResources().getDrawable(R.drawable.favorite_blank_content_selector));
                    showSnackbar("I thought that was one of your favorites.");
                } else {
                    isFavorited = true;
                    btnFavorite.setBackground(getActivity().getResources().getDrawable(R.drawable.favorite_content_selector));
                }
                break;
        }

    }

    private void showSnackbar(String msg) {
        Snackbar
                .make(view, msg, Snackbar.LENGTH_LONG)
                .setAction(R.string.snackbar_action, mOnClickListener)
                .setActionTextColor(getActivity().getResources().getColor(R.color.material_yellow_400))
                .show();
    }


    /**
     * 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);
    }

    public Movie getMovie() {
        return movie;
    }
}
Coova
  • 1,758
  • 4
  • 30
  • 56

2 Answers2

3

Instead of calling

adapter = new DetailFragmentPagerAdapter(getActivity().getSupportFragmentManager(), getActivity(), getMovie());

try:

adapter = new DetailFragmentPagerAdapter(getChildFragmentManager(), getActivity(), getMovie());
Bartek Lipinski
  • 27,311
  • 8
  • 79
  • 116
0

This is also working for me.

Basically, the difference is that Fragment's now have their own internal FragmentManager that can handle Fragments. The child FragmentManager is the one that handles Fragments contained within only the Fragment that it was added to. The other FragmentManager is contained within the entire Activity.

for further detail about getChildFragmentManager() visit this question

[What is difference between getSupportFragmentManager() and getChildFragmentManager()?