简体   繁体   中英

How can I write a method with a fragment class as an argument that will allow me to create a new instance of that fragment?

The Goal

I'm trying to write a method that would replace the code that I use to swap fragments in order to keep copying and posting to a minimum (and to stay DRY)

The Problem

I get an error when I attempt to use the class that I passed in as an argument to create a new instance of that class.

The error occurs in this line of code, to the left of the operator (equal sign):

 newFragmentClass new_fragment = newFragmentClass.newInstance(); 

The error it gives me is: "newFragmentClass cannot be resolved to a type".

Full Code
  private void changeFragment(Class<?> newFragmentClass) { // Detect the current fragment Fragment current_fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container); // Create a new instance of the given class, edit later to gracefully handle errors newFragmentClass new_fragment = newFragmentClass.newInstance(); // Switch to the new fragment FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); transaction.detach(current_fragment); transaction.replace(R.id.fragment_container, new_fragment); transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); transaction.commit(); // Change the tab background to indicate that the tab is active, reset backgrounds for any other tabs findViewById(R.id.page_one_tab).setBackgroundResource(R.drawable.menu_button_background_active); findViewById(R.id.page_two_tab).setBackgroundResource(R.drawable.menu_button_background); findViewById(R.id.page_three_tab).setBackgroundResource(R.drawable.menu_button_background); } // Page One Tab Button Functionality public void pageOneTab (View v) { // Change the fragment to SelectPlayersFragment changeFragment(Page_One_Fragment.class); } 
Attempted Solutions

I've been searching StackOverflow and the internet at large for quite a while and have not been able to find a solution. A few topics like this one seemed as if they would resolve the problem, but then I ran into an error on the transaction.replace line that I could not find a fix for: "The method replace(int, Fragment) in the type FragmentTransaction is not applicable for the arguments (int, Object)".

You probably want something like:

private Fragment changeFragment(Class<? extends Fragment> newFragmentClass)  {
    Fragment current_fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
    // Create a new instance of the given class, edit later to gracefully handle errors
    Fragment new_fragment = null;
    try {
         new_fragment = newFragmentClass.newInstance();
    } catch (InstantiationException e) {            
        throw new RuntimeException(e); // for some reason this fragment loading has failed so crash
    } catch (IllegalAccessException e) {            
        throw new RuntimeException(e);
    } 
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    transaction.detach(current_fragment);
    transaction.replace(R.id.fragment_container, new_fragment);
    // ...   

Perhaps a more simpler solution would be to pass a Fragment as argument, instead of a Class , and use it to replace the current fragment. Also, you don't need to detach the current fragment, that is what replace() does for you.

Something like this:

public void changeFragment(Fragment fragment) {
    FragmentManager manager = getSupportFragmentManager();
    FragmentTransaction transaction = manager.beginTransaction();
    transaction.replace(R.id.fragment_container, fragment, "tag");
    transaction.commit();
    //.....
}

And you use it like this:

changeFragment(new Page_One_Fragment());

I think you want this:

private <T extends Fragment> void changeFragment(Class<T> newFragmentClass)
{
    ...
    // Create a new instance of the given class, edit later to gracefully handle errors
    T new_fragment = newFragmentClass.newInstance(); 
    ...
}

Because your "newFragmentClass' is only a parameter of method, it's not a type so you can not instance it. Follow my code to fix your problem

private <T extends Fragment> void changeFragment(Class<T> newFragmentClass)
    {
        // Detect the current fragment
            Fragment current_fragment = getSupportFragmentManager().findFragmentById(R.id.content);

        // Create a new instance of the given class, edit later to gracefully handle errors
            T new_fragment = newFragmentClass.newInstance(); 

        // Switch to the player select fragment
            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
            transaction.detach(current_fragment);
            transaction.replace(R.id.fragment_container, new_fragment);
            transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
            transaction.commit();

        // Change the tab background to indicate that the tab is active, reset backgrounds for any other tabs
            findViewById(R.id.page_one_tab).setBackgroundResource(R.drawable.menu_button_background_active);
            findViewById(R.id.page_two_tab).setBackgroundResource(R.drawable.menu_button_background);
            findViewById(R.id.page_three_tab).setBackgroundResource(R.drawable.menu_button_background);

    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM