2017-02-24 78 views
3

我一直試圖在我的應用程序中動態地替換一個片段,但是當我這樣做的時候我不斷收到一個RuntimeException,因爲它找不到它應該添加片段的容器ID。我嘗試過在類似線程上找到的每個解決方案,從乾淨構建到使用ChildFragmentManager,但仍然存在相同的錯誤。 最奇怪的是,當我在onCreate中指定沒有容器時,一切都很順利,但只要指定了容器,應用就會崩潰。下面是代碼和堆棧跟蹤:RuntimeException當動態替換一個片段

堆棧跟蹤:

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> 

編輯:我試着檢查R.java,看看Id是否搞砸了,但看起來好像一切正​​常,並且fragment_container id顯然已經存在。也試圖清理項目,但正如我所料,這並沒有改變任何東西。我嘗試用replace()替換add,但仍然是相同的錯誤,除非我使用android.R.id.container作爲容器。我正在使用數據綁定,也許這是衝突的原因?

編輯2:我創建了一個新的項目,我做了同樣的事務,但是用一個簡單的片段顯示一個簡單的TextView,並且一切看起來都很好,沒有發生碰撞。所以我試圖刪除我的片段中的模糊項目,如回調,但我仍然得到同樣的錯誤。 DataBinding似乎不是問題,因爲我嘗試了沒有它,仍然得到相同的堆棧跟蹤。

謝謝你的幫助。

+0

順便說一下......「認證」,而不是「認證」 –

+0

這是在法國! – tarzan212

+0

:)其餘的變量是英語...反正..'fragment_container'肯定存在,你只使用它三個點,但錯誤來自一個活動的'onStart',它不清楚在哪裏 –

回答

1

在你的代碼的問題是,你正試圖將signInFragment UI其在onCreate方法的行爲約束,但這種方法onCreateView之前稱爲你可以在fragment lifecycle看到。

如果您將onCreate方法的內容移動到onCreateView或以後調用的任何方法中,您將不會再發生此故障。

+0

謝謝!這解決了我的主要問題,但是,當我點擊應該顯示SignUpFragment的按鈕時,即使將大部分關鍵代碼移動到onActivityCreated(),我也會得到IllegalStateArgument異常。任何提示?我正在考慮擺脫DataBinding,因爲它迄今爲止只造成了一些問題。 – tarzan212