Reputation: 1858
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;
}
}
Upvotes: 0
Views: 1123
Reputation: 412
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()?
Upvotes: 0
Reputation: 31438
Instead of calling
adapter = new DetailFragmentPagerAdapter(getActivity().getSupportFragmentManager(), getActivity(), getMovie());
try:
adapter = new DetailFragmentPagerAdapter(getChildFragmentManager(), getActivity(), getMovie());
Upvotes: 3