当前位置: 首页 > 知识库问答 >
问题:

动态替换片段时的RuntimeException

百里景山
2023-03-14

我一直在尝试在我的应用程序中动态替换一个片段,但这样做时,我一直会遇到RuntimeException,因为它找不到应该添加片段的容器ID。我尝试过在类似线程上找到的每一个解决方案,从干净的构建到使用ChildFragmentManager,但仍然有相同的错误。最奇怪的是,当我在onCreate中没有指定任何容器时,一切都很顺利,但一旦指定了容器,应用程序就会崩溃。以下是代码和堆栈跟踪:

堆栈跟踪:

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) 

认证活动:

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;


        }



    }
}

重要片段:

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);
    }
}

活动认证。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_containerid明显存在。我还尝试清理项目,但正如我所料,这并没有改变任何事情。我尝试用替换()替换add,但仍然是相同的错误,除了当我使用android时。R.id.container作为容器。我正在使用数据绑定,也许这是冲突的原因?

EDIT2:我已经创建了一个新项目,在那里我做了相同的事务,但有一个简单的片段显示了一个简单的文本视图,而且一切似乎都很好,没有崩溃的迹象。所以我试着删除片段中的模糊项,比如回调,但我还是犯了同样的错误。数据绑定似乎不是问题,因为我尝试不使用它,但仍然得到相同的堆栈跟踪。

谢谢你的帮助。

共有1个答案

程修雅
2023-03-14

代码中的问题是,您试图将signInFragmentUI绑定到onCreate方法中的行为,但是这个方法在onCreateView之前调用,正如您在片段生命周期中看到的那样。

如果您在onCreateView中移动onCreate方法的内容,或者以后调用的任何方法,您将不会再发生此崩溃。

 类似资料:
  • 在我的应用程序中,当点击导航抽屉上的不同项目时,我需要在片段之间切换。我为它创建了一个新方法DisplayFragment。代码如下: 它显示了错误的"片段元素在上面的行如下"错误的第二个参数类型找到android.support.v4.app.片段;需要android.app.片段;" 我试着改变从android的导入。支持v4.app。碎片到android。应用程序。碎片但它随后显示了Frag

  • 我有一个活动,它包含一个片段容器(FrameLayout),我在Activity.onCreate()期间在其中放置了一个片段。片段包含一个包含一串片段的ViewPager。所有这些工作都很好。页面内容显示,我可以很好地在页面中滑动,甚至可以看到操作栏中的操作,因为贡献的页面变得可见。 现在我用另一个片段替换包含ViewPager的片段: 此外,我已经用FragmentPagerAdapter替换

  • 我正在创建一个包含三个视图的可视寻呼机。第一个视图是ListView,onItemClick用WebView替换了这个片段。而且我有两个问题:当添加' transaction . addtobackstack(null)'或者' transaction . setcustomanimations(...)'片段与WebView stopps一起显示。如果没有这几行,它会显示出来,但我不能按后退按钮

  • 问题内容: 我在小组活动中有一个片段,我想用另一个片段替换它: 在不使用活动组的情况下作为单独的项目完成时,它工作正常,当控件进入getview()时,每件事在日志猫中都可以正常工作,但是没有视图可见,甚至没有任何异常出现,我希望将书详细信息片段由部分详细信息片段代替。 图书详细信息片段的XML具有id book_description_fragment,而部分描述片段的xml具有id secti

  • 我有以下布局 一切正常,但我想用一个片段替换浏览器 这不是重新调整ViewPager的间距,我该怎么办???

  • 我试图通过活动中按钮的onclick事件将一个主片段替换为另一个片段,但该片段恰好悬停在主片段上。 这是我的密码