2017-02-24 7 views
3

Ich habe versucht, ein Fragment dynamisch in meiner App zu ersetzen, aber ich bekomme immer eine RuntimeException, da es die Container-ID nicht finden kann, die das Fragment hinzugefügt werden soll. Ich habe jede einzelne Lösung ausprobiert, die ich in ähnlichen Threads gefunden habe, von einem sauberen Build bis zur Verwendung eines ChildFragmentManagers, aber trotzdem habe ich denselben Fehler. Die seltsamste Sache ist, dass, wenn ich keinen Container in der onCreate angeben, alles gut geht, aber sobald ein Container angegeben ist, stürzt die App ab. Hier ist der Code und die Stack-Trace:RuntimeException beim dynamischen Ersetzen eines Fragments

Stack Trace:

E/AndroidRuntime: FATAL EXCEPTION: main 
        Process: com.example.user.onceuponatime, PID: 23668 
        java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.user.onceuponatime/com.example.user.onceuponatime.activity.AuthentificationActivity}: java.lang.IllegalArgumentException: No view found for id 0x7f0d007f (com.example.user.onceuponatime:id/fragment_container) for fragment SignInFragment{42d6c688 #0 id=0x7f0d007f signinfragment} 
         at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2394) 
         at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2452) 
         at android.app.ActivityThread.access$900(ActivityThread.java:172) 
         at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1302) 
         at android.os.Handler.dispatchMessage(Handler.java:102) 
         at android.os.Looper.loop(Looper.java:136) 
         at android.app.ActivityThread.main(ActivityThread.java:5586) 
         at java.lang.reflect.Method.invokeNative(Native Method) 
         at java.lang.reflect.Method.invoke(Method.java:515) 
         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268) 
         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084) 
         at dalvik.system.NativeStart.main(Native Method) 
        Caused by: java.lang.IllegalArgumentException: No view found for id 0x7f0d007f (com.example.user.onceuponatime:id/fragment_container) for fragment SignInFragment{42d6c688 #0 id=0x7f0d007f signinfragment} 
         at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1293) 
         at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528) 
         at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595) 
         at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:757) 
         at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2355) 
         at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2146) 
         at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2098) 
         at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2008) 
         at android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:388) 
         at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:607) 
         at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:178) 
         at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1177) 
         at android.app.Activity.performStart(Activity.java:5461) 
         at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2367) 
         at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2452)  
         at android.app.ActivityThread.access$900(ActivityThread.java:172)  
         at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1302)  
         at android.os.Handler.dispatchMessage(Handler.java:102)  
         at android.os.Looper.loop(Looper.java:136)  
         at android.app.ActivityThread.main(ActivityThread.java:5586)  
         at java.lang.reflect.Method.invokeNative(Native Method)  
         at java.lang.reflect.Method.invoke(Method.java:515)  
         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)  
         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)  
         at dalvik.system.NativeStart.main(Native Method)  

AuthentificationActivity:

public class AuthentificationActivity extends AppCompatActivity implements SignInFragment.SignInFragmentCallBack 
     ,SignUpFragment.SignUpFragmentCallBack{ 

    public static final String SIGNINFRAGMENT_TAG = "signinfragment"; 
    public static final String SIGNUPFRAGMENT_TAG = "signupfragment"; 

    public static final int SIGNIN_FRAGMENT_ID = 846464; 
    public static final int SIGNUP_FRAGMENT_ID = 125478; 
    public static final int LOST_PWD_FRAGMENT_ID = 85546; 

    private FragmentManager mFragmentManager; 
    private SignInFragment mSignInFragment; 
    private SignUpFragment mSignUpFragment; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_authentification); 


     mSignInFragment = SignInFragment.getInstance(); 

     mFragmentManager = getSupportFragmentManager(); 
     FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction(); 


     fragmentTransaction.add(R.id.fragment_container,mSignInFragment,SIGNINFRAGMENT_TAG); 
     fragmentTransaction.addToBackStack(null); 
     fragmentTransaction.commit(); 


    } 

    @Override 
    public void onFragmentSwapRequested(int FragmentId) { 

     mFragmentManager = this.getSupportFragmentManager(); 

     FragmentTransaction fgTransaction = mFragmentManager.beginTransaction(); 

     switch(FragmentId) { 
      case SIGNUP_FRAGMENT_ID: 
       if(!isFinishing()) { 
        mSignUpFragment = (SignUpFragment) mFragmentManager.findFragmentByTag(SIGNUPFRAGMENT_TAG); 
        if (mSignUpFragment == null) { 
         mSignUpFragment = SignUpFragment.getInstance(); 
         fgTransaction.replace(R.id.fragment_container, mSignUpFragment, SIGNUPFRAGMENT_TAG); 
        } else { 
         fgTransaction.show(mSignUpFragment); 
        } 
        fgTransaction.addToBackStack(null); 
        fgTransaction.commit(); 
       } 
       break; 
      case LOST_PWD_FRAGMENT_ID: 
       break; 


     } 



    } 
} 

SignInFragment:

public class SignInFragment extends Fragment { 
    FragmentSignInBinding signInBinding; 

    private CoordinatorLayout mCoordinatorLayout; 
    private EditText mEmailEdit,mPasswordEdit; 
    private Button btnSignIn,btnSignUp,btnLostPwd; 
    private ProgressBar mProgressBar; 

    private FirebaseAuth mAuth; 

    private SignInFragmentCallBack mCallBack; 



    public interface SignInFragmentCallBack { 
     void onFragmentSwapRequested(int FragmentId); 
    } 

    public SignInFragment() {} 


    public static SignInFragment getInstance() { 
     return new SignInFragment(); 
    } 

    @Override 
    public void onAttach(Context context) { 
     super.onAttach(context); 
     try { 
      mCallBack = (SignInFragmentCallBack) context; 
     } catch(ClassCastException e) { 
      throw new ClassCastException(context.toString() + " must implements SignInCallaback"); 
     } 
     Toast.makeText(context,mCallBack.toString(),Toast.LENGTH_LONG).show(); 
    } 

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

     signInBinding = DataBindingUtil.setContentView(getActivity(),R.layout.fragment_sign_in); 
     mEmailEdit = signInBinding.emailSignin; 
     mPasswordEdit = signInBinding.passwordSignin; 
     mProgressBar = signInBinding.progressBarSignIn; 
     btnSignIn = signInBinding.signInButton; 
     btnSignUp = signInBinding.signUpButton; 
     btnLostPwd = signInBinding.passwordReset; 
     mCoordinatorLayout = signInBinding.coordinatorSignin; 



     mAuth = FirebaseAuth.getInstance(); 



     btnSignIn.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       signInAction(); 
      } 
     }); 

     btnSignUp.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       if(mCallBack instanceof SignInFragmentCallBack) 
       mCallBack.onFragmentSwapRequested(AuthentificationActivity.SIGNUP_FRAGMENT_ID); 
      } 
     }); 

     btnLostPwd.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       if(mCallBack instanceof SignInFragmentCallBack) 
       mCallBack.onFragmentSwapRequested(AuthentificationActivity.LOST_PWD_FRAGMENT_ID); 
      } 
     }); 


    } 

    private void signInAction() { 
     String email = mEmailEdit.getText().toString().trim(); 
     final String password = mPasswordEdit.getText().toString().trim(); 

     if(TextUtils.isEmpty(email)) { 
      Snackbar.make(mCoordinatorLayout,getString(R.string.no_email_entered),Snackbar.LENGTH_LONG).show(); 
      return; 
     } 

     if(TextUtils.isEmpty(password)) { 
      Snackbar.make(mCoordinatorLayout,getString(R.string.no_password_entered),Snackbar.LENGTH_LONG).show(); 
      return; 
     } 

     mProgressBar.setVisibility(View.VISIBLE); 
     mAuth.signInWithEmailAndPassword(email,password).addOnCompleteListener(getActivity(), new OnCompleteListener<AuthResult>() { 
      @Override 
      public void onComplete(@NonNull Task<AuthResult> task) { 
       mProgressBar.setVisibility(View.GONE); 
       if(task.isSuccessful()) { 
        Snackbar.make(mCoordinatorLayout,getString(R.string.login_success),Snackbar.LENGTH_LONG).show(); 
        startActivity(new Intent(getActivity(), MainActivity.class)); 
        getActivity().finish(); 
       } 
       else 
       { 
        Snackbar.make(mCoordinatorLayout,getString(R.string.login_failed),Snackbar.LENGTH_LONG).show(); 

       } 
      } 
     }); 
    } 


    @Nullable 
    @Override 
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 
     return inflater.inflate(R.layout.fragment_sign_in,container,false); 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 
     mProgressBar.setVisibility(View.GONE); 
    } 
} 

activity_authentification.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@+id/activity_authentification" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context="com.example.user.onceuponatime.activity.AuthentificationActivity"> 

<FrameLayout 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:id="@+id/fragment_container"/> 



</LinearLayout> 

BEARBEITEN: Ich versuchte, die R.java zu überprüfen, um zu sehen, ob die Id's durcheinander waren, aber es scheint, als ob alles in Ordnung ist, mit der ID fragment_container klar existent. Auch versucht, das Projekt zu säubern, aber wie ich erwartet hatte, änderte das nichts. Ich habe versucht, ersetzen mit ersetzen(), aber immer noch, der gleiche Fehler, außer wenn ich android.R.id.container als Container verwenden. Ich verwende Datenbindung, vielleicht ist es die Ursache des Konflikts?

EDIT2: Ich habe ein neues Projekt erstellt, wo ich die gleiche Transaktion aber mit einem einfachen Fragment eine einfache TextView angezeigt, und alles scheint gut zu funktionieren, kein Absturz in Sicht. Also habe ich versucht, die mehrdeutigen Elemente in meinem Fragment wie den Rückruf zu löschen, aber ich bekomme immer noch den gleichen Fehler. DataBinding scheint nicht das Problem zu sein, da ich ohne es versuchte und immer noch die gleiche Stack-Trace bekommen.

Vielen Dank für Ihre Hilfe.

+0

Übrigens ... "Authentifizierung", nicht "Authentifizierung" –

+0

Es ist in Französisch! – tarzan212

+0

:) Der Rest der Variablen ist Englisch ... Anyways .. 'fragment_container' definitiv existiert, und Sie verwenden es nur drei Spots, aber der Fehler kommt von einem' onStart' einer Aktivität, die es nicht klar ist, wo –

Antwort

1

Das Problem in Ihrem Code ist, dass Sie versuchen, den signInFragment UI zu seinem Verhalten in der onCreate Methode zu binden, aber diese Methode vor onCreateView aufgerufen wird, wie man auf den fragment lifecycle sehen kann.

Wenn Sie den Inhalt Ihrer onCreate-Methode in Ihre onCreateView oder eine der folgenden Methoden verschieben, haben Sie diesen Absturz nicht mehr.

+0

Danke! Das hat mein Hauptproblem behoben, aber wenn ich auf die Schaltfläche klicke, die das SignUpFragment anzeigen soll, bekomme ich die IllegalStateArgument-Ausnahme, obwohl ich den Großteil des kritischen Codes auf onActivityCreated() verschoben habe. Irgendwelche Hinweise? Ich denke nur daran, die DataBinding loszuwerden, da sie bisher nur Probleme verursacht hat. – tarzan212

Verwandte Themen