Reputation: 408
I have been trying to replace a fragment dynamically in my app , but I keep getting a RuntimeException when doing so , as it can't find the container ID it is supposed to add the fragment to . I have tried every single solution I found on similar threads , from doing a clean build to using a ChildFragmentManager but still , I have the same error . The weirdest thing is that when I specify no container in the onCreate , everything goes fine but as soon as a container is specified , the app crashes . Here is the code and the stack trace :
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>
EDIT : I tried checking the R.java to see if the Id's were messed up but it seems like everything is fine , with the fragment_container id clearly exisisting . Also tried cleaning the project but as I expected , this didn't change anything . I tried replacing add with replace() but still , same error , except when I use android.R.id.container as the container . I am using data binding , maybe it's the cause of the conflict ?
EDIT2 : I have created a new project where I did the same transaction but with a simple fragment displaying a simple TextView , and everything seems to work fine , no crash in sight . So I tried deleting the ambiguous items in my fragment such as the callback , but I still get the same mistake . DataBinding doesn't seem to be the issue since I tried without it and still get the same stack trace .
Thank you for your help.
Upvotes: 3
Views: 1197
Reputation: 1551
The problem in your code is that you are trying to bind the signInFragment
UI to its behavior in the onCreate
method, but this method is called before onCreateView
as you can see on the fragment lifecycle.
If you move the content of your onCreate
method in your onCreateView
, or any method called afterward you won't have this crash anymore.
Upvotes: 1