问题
I am trying to create a ViewPager which contains 5 fragments. 5 fragments "container", so each of them contain 2 fragments. The 4 first fragments have the same layout and belong to the same class. The fifth is from an other class, and there is no problem with that one.
The problem is that when the activity launches, only 1 fragment seem to be working (the one at position 0 in viewPager). I tried to return new Fragment() at position 0 in my PagerAdapter, but when I do that it's the 2nd fragment that is working. (By working i mean displaying the list on the left, I still haven't taken care of the details fragment on the right)
Here is some code
CustomPagerAdapter.java
public class CustomPagerAdapter extends FragmentPagerAdapter{
public CustomPagerAdapter(FragmentManager fm) {
super(fm);
}
public CustomPagerAdapter(FragmentManager fm, Context context) {
super(fm);
}
@Override
public Fragment getItem(int pos) {
if(pos == 4)
return new OtherContainerFragment();
else
return new ContainerFragment(pos);
}
@Override
public int getCount() {
return 5;
}
ContainerFragment.java
public class ContainerFragment extends Fragment {
private int CONTAINER_TYPE;
public ContainerFragment(){
}
public ContainerFragment(int type){
CONTAINER_TYPE = type;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_container, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
CustomListFragment frag = new CustomListFragment(CONTAINER_TYPE);
ft.replace(R.id.replaceable_list, frag);
ft.commit();
CustomListFragment.java
public class CustomListFragment extends SuperCustomListFragment{
private ArrayList<Model> mModels;
private int TYPE;
public CustomListFragment(){
}
public CustomListFragment(int type){
TYPE = type;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return super.onCreateView(inflater, container, savedInstanceState);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mModels = new ArrayList<Model>();
if(TYPE == AppConstants.FRAGMENT_TYPE_JOURNAL){
mAdapter = AppUtils.getJournalListAdapter(getActivity(), mModels);
new syncPapers().execute();
}else if(TYPE == AppConstants.FRAGMENT_TYPE_MOVIES){
mAdapter = AppUtils.getMoviesListAdapter(getActivity(), mModels);
new syncMovies().execute();
}
if(mAdapter != null)
mListView.setAdapter(mAdapter); //mListView is defined in the superClass
Here are the constants I use :
public class AppConstants {
public static final int FRAGMENT_TYPE_AGENDA = 0; //so Fragment at position 0 should be of type agenda
public static final int FRAGMENT_TYPE_NEWS = 1; // position 1 should be of type news
public static final int FRAGMENT_TYPE_MOVIES = 2; // ...
public static final int FRAGMENT_TYPE_JOURNAL = 3; // ...
}
And the xml for the container :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<LinearLayout
android:id="@+id/replaceable_list"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</LinearLayout>
<LinearLayout
android:id="@+id/replaceable_details"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/background" >
</LinearLayout>
</LinearLayout>
SO this code is not working, it seems that the list on the left in the fragment container is replaced in each fragment, and only the fragment at position 0 displays it. (Currently it displays the list with the adapter of type "JOURNAL", but it should display list of type "AGENDA".
-------------------- *BUT !...* --------------------
If I create different fragment_container layout-files, and write IF conditions in the onCreateView and onViewCreated in the ContainerFragment.java, everything works fine. So :
ContainerFragment.java
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if(CONTAINER_TYPE == AppConstants.FRAGMENT_TYPE_JOURNAL)
return inflater.inflate(R.layout.fragment_container_journal, container, false);
else if(CONTAINER_TYPE == AppConstants.FRAGMENT_TYPE_MOVIES)
return inflater.inflater(R.layout.fragment_container_movies, container, false);
else
return super.onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
CustomListFragment frag = new CustomListFragment(CONTAINER_TYPE);
if(CONTAINER_TYPE == AppConstants.FRAGMENT_TYPE_JOURNAL)
ft.replace(R.id.replaceable_journal_list, frag);
else if(CONTAINER_TYPE == AppConstants.FRAGMENT_TYPE_MOVIES)
ft.replace(R.id.replaceable_movies_list, frag);
else
return;
ft.commit();
I guess that's because in each fragment, I replace the LinearLayout of the same ID ? (replaceable_list) I thought it was possible to share the same layout file for every fragments and didn't want to create 4 layout-files that would be the same. But it looks like I must do so ? Or am I missing something here ?
Thank you for your time,
回答1:
Though a very late response but I was facing same kind of issue and I fixed the issue by using
getChildFragmentManager().beginTransaction()
instead of
getActivity().getSupportFragmentManager().beginTransaction()
As in this case we are trying to make transaction from within a fragment (one out of the list of fragments which are attached to the ViewPager, thus the Activity holding the ViewPager) so we have to use getChildFragmentManager() here for desired results.
回答2:
I was able to solve this by setting the id of the layout that is inflated within each fragment to its position.
What you would have to do is simply change the method onCreateView in you ContainerFragment class to:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_container, container, false);
v.setId(CONTAINER_TYPE)
return v;
This works because of the way the FragmentPagerAdapter implementation handles fragment tags.
来源:https://stackoverflow.com/questions/19757035/viewpager-with-multiple-fragment-instances-of-same-class