Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

As mentioned in my previous question I had some problem with showing Fragments inside a ViewPager after opening another Fragment from one of the Fragments inside the ViewPager.

I somehow managed to resolve the problem by using add() in the FragmentTransaction. Unfortunately this creates another problem:

I am using the ActionBar in my app. When I am selecting the same menu item twice I encounter the same problem as before, it doesn't show any Fragments inside the ViewPager.

Home Activity Code(where action bar on click events are call)

public class HomePageActivity extends SherlockFragmentActivity implements ICallback {

    private DrawerLayout mDrawerLayout;
    private ListView mDrawerList;
    private SherlockActionBarDrawerToggle mDrawerToggle;

    private CharSequence mDrawerTitle;
    private CharSequence mTitle;
    private String[] mChampionsMenuItems;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setTheme(R.style.Theme_Sherlock);
        setContentView(R.layout.activity_home_page);

        mTitle = mDrawerTitle = getTitle();
        mChampionsMenuItems = getResources().getStringArray(R.array.champions_array);
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerList = (ListView) findViewById(R.id.left_drawer);

        mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
        mDrawerList.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, mChampionsMenuItems));
        mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setHomeButtonEnabled(true);    
        getSupportActionBar().setBackgroundDrawable(getResources().getDrawable(R.color.navy_blue));
        getSupportActionBar().setDisplayShowTitleEnabled(false);

        mDrawerToggle = new SherlockActionBarDrawerToggle(this, mDrawerLayout, R.drawable.menu_icon, R.string.drawer_open, R.string.drawer_close) {

            public void onDrawerClosed(View view) {
                getSupportActionBar().setTitle(mTitle);
                supportInvalidateOptionsMenu();
            }

            public void onDrawerOpened(View drawerView) {
                getSupportActionBar().setTitle(mDrawerTitle);
                supportInvalidateOptionsMenu();
            }
        };
        mDrawerLayout.setDrawerListener(mDrawerToggle);

        if (savedInstanceState == null) {
            onFragmentChange(new HomeActivityFragment(), true);
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (mDrawerToggle.onOptionsItemSelected(item)) {
            return true;
        }

        switch (item.getItemId()) {
            default: return super.onOptionsItemSelected(item);
        }
    }

    private class DrawerItemClickListener implements ListView.OnItemClickListener {

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            selectItem(position);
        }
    }

    private void selectItem(int position) {    
        switch (position) {

            case 0:
                onFragmentChange(new Fragment1(), false);
                break;

            case 1:
                onFragmentChange(new Fragment2(), false);
                break;

            case 2:
                onFragmentChange(new MyPointFragment3(), false);
                break;

            case 3:
                // onFragmentChange(new HomeActivityFragment(), true);
                break;

            case 4:
                onFragmentChange(new QueriesFragment(), false);
                break;

            case 5:
                onFragmentChange(new GalleryFragment(), false);
                break;

            default:
                break;
        }

        mDrawerList.setItemChecked(position, true);
        mDrawerLayout.closeDrawer(mDrawerList);

    }

    @Override
    public void setTitle(CharSequence title) {
        mTitle = title;
        getSupportActionBar().setTitle(mTitle);
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        mDrawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        mDrawerToggle.onConfigurationChanged(newConfig);
    }

    @Override
    public void onFragmentChange(Fragment fragment, boolean flag) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.add(R.id.content_frame, fragment, fragment.getClass().getName());
        transaction.commit();
    }    
}

This is the Fragment which contains the ViewPager:

public class Fragment1 extends Fragment implements OnClickListener {

        ICallback callback;
        private LinearLayout headerContainer;
        private ImageView headerLogo;
        private TextView headerName;
        private Button menuBarButton;

        MyAdapter adapter;
        ViewPager pager;
        ActionBar actionBar;

        private Button progOverview, progStr, bonusPoint;

        @Override
        public void onAttach(Activity activity) {
            super.onAttach(activity);
            if (activity instanceof ICallback) {
                this.callback = (ICallback) activity;
            }
            actionBar = activity.getActionBar();
            actionBar.show();
        }

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

        private View setUpView(LayoutInflater inflater, ViewGroup container) {

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

            headerContainer = (LinearLayout) rootView.findViewById(R.id.second_top_header);
            headerContainer.setBackgroundColor(getResources().getColor(R.color.prog_str_blue));
            headerLogo = (ImageView) rootView.findViewById(R.id.header_logo);
            headerLogo.setBackgroundResource(R.drawable.about_champions_ticon);
            headerName = (TextView) rootView.findViewById(R.id.header_name);
            headerName.setText(R.string.about_champ_title);

            adapter = new MyAdapter(getFragmentManager());
            pager = (ViewPager) rootView.findViewById(R.id.pager);
            pager.setAdapter(adapter);

            return rootView;
        }


        @Override
        public void onSaveInstanceState(Bundle outState) {
            super.onSaveInstanceState(outState);
        }

        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            if (savedInstanceState != null) {
                // Restore last state for checked position.
            }
        }
        }  
    }

This is one of the Fragments inside the ViewPager:

public class ProgramOverViewFragment extends Fragment {

    ICallback callback;

    @Override
    public void onAttach(Activity activity) {           
        super.onAttach(activity);
        if (activity instanceof ICallback) {
            this.callback = (ICallback) activity;
        }    
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_program_overview, container, false);

        TextView termsAndCond = (TextView) rootView.findViewById(R.id.terms_and_condition_button);
        termsAndCond.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                FragmentManager fragmentManager = getSupportFragmentManager();
                FragmentTransaction transaction = fragmentManager.beginTransaction();
                transaction.replace(R.id.content_frame, fragment);
                fragment.setRetainInstance(true);
                transaction.addToBackStack(null);
                transaction.commit();    
            }
        });

        return rootView;
    }
}

My FragmentStatePagerAdapter:

public class MyAdapter extends FragmentStatePagerAdapter {    

    public MyAdapter(FragmentManager fm) {
        super(fm);    
    }

    @Override
    public android.support.v4.app.Fragment getItem(int index) {
        switch (index) {
            case 0: return new ProgramOverViewFragment();
            case 1: return new ProgramStructureFragment();
            case 2: return new BonusPointFragment();
        }
        return null;
    }

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

Thanks for your help!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
121 views
Welcome To Ask or Share your Answers For Others

1 Answer

What do you want to do exactly? Are you trying to replace a Fragment inside the ViewPager? Or are you trying to replace a Fragment inside a Fragment inside the ViewPager? Or are you trying to do something different altogether? I can only give you an accurate solution if you explain what you are trying to do in detail. Anyway here is what I am guessing might be wrong:


I think your problem is that you use the wrong FragmentManager. There are multiple different FragmentManagers, but essentially there are two cases:

  1. You want to add/replace/remove a Fragment from an Activity
  2. You want to add/replace/remove a Fragment from another Fragment

As long as I don't see your layout files I can't be sure which of those two options fits your situation.


Solution if you want to replace a Fragment inside of another Fragment

If you want to perform a FragmentTransaction on a Fragment inside of another Fragment, then you need to use the child FragmentManager! You can use the child FragmentManager inside a Fragment like this:

FragmentManager fragmentManager = getChildFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.content_frame, fragment);
fragment.setRetainInstance(true);
transaction.addToBackStack(null);
transaction.commit();

As you can see you just need to use getChildFragmentManager() instead of getSupportFragmentManager()


As I already said, without any further information about your situation I cannot give you a more accurate answer. So please try to explain what you want to do as best as you can to me and I'm confident we can solve this.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...