InflateException,因为Fragment没有创建视图

时间:2016-01-25 16:37:01

标签: android inflate-exception

我正在开发一个Android应用程序,我正在使用Fabric / Crashlytics推送给测试人员。

我自己在2台物理设备上彻底测试了我的应用程序:

  1. Samsung Galaxy Tab Pro运行4.4.2(API 19)
  2. LG G3正在运行5.0.1(API 21)
  3. 我最近将一个版本的应用程序推送给了一个测试人员。她的设备是:

    • 三星Galaxy S4运行5.0.1(API 21)

    我正在尝试使用登录/注册Activity / Fragment系列。我通过Crashlytics收到崩溃报告,其中包含以下信息:

    以下是日志的摘录:

    Fatal Exception: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.company.app/com.company.app.LoginActivity}: android.view.InflateException: Binary XML file line #70: Error inflating class fragment
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2693)
        ... other lines
    Caused by android.view.InflateException: Binary XML file line #70: Error inflating class fragment
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:770)
        ... other lines
        at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:256)
        at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:109)
        at com.company.app.LoginActivity.onCreate(LoginActivity.java:25)
        at android.app.Activity.performCreate(Activity.java:6289)
        ... other lines
    Caused by java.lang.IllegalStateException: Fragment com.company.app.LoginFragment did not create a view.
        at android.app.FragmentManagerImpl.onCreateView(FragmentManager.java:2160)
        at android.app.Activity.onCreateView(Activity.java:5610)
        at android.support.v4.app.BaseFragmentActivityHoneycomb.onCreateView(BaseFragmentActivityHoneycomb.java:34)
        at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:79)
        ... other lines
        at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:256)
        at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:109)
        at com.company.app.LoginActivity.onCreate(LoginActivity.java:25)
        at android.app.Activity.performCreate(Activity.java:6289)
        ... other lines
    

    以下是我的LoginActivity和LoginFragment文件的精简版本:

    activity_login.xml

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.design.widget.CoordinatorLayout>
        <LinearLayout>
            <android.support.v7.widget.Toolbar>
                <LinearLayout>
                    <TextView />
                    <ImageButton />
                </LinearLayout>
            </android.support.v7.widget.Toolbar>
            <FrameLayout>
                <fragment
                    android:id="@+id/container"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:name="com.company.app.LoginFragment"
                    tools:layout="@layout/fragment_login" />
                <View />
            </FrameLayout>
        </LinearLayout>
    </android.support.design.widget.CoordinatorLayout>
    

    LoginActivity.java

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        // This next line causes the error
        setContentView(R.layout.activity_login);
    
        ImageButton infoButton = (ImageButton)findViewById(R.id.info_button);
        infoButton.setColorFilter(ContextCompat.getColor(this, R.color.colorPrimary), PorterDuff.Mode.SRC_ATOP);
        infoButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mUserCreationFragment != null) {
                    mUserCreationFragment.showInfo();
    
                } else if (mEnterCodesFragment != null) {
                    mEnterCodesFragment.showInfo();
    
                } else if (mLoginFragment != null) {
                    mLoginFragment.showInfo();
    
                }
            }
        });
        mToolbar                = (Toolbar)findViewById(R.id.toolbar);
        mTitleLabel             = (TextView)findViewById(R.id.title_label);
        mTitleLabel.setText(getString(R.string.login_string));
        setSupportActionBar(mToolbar);
    
    }
    

    fragment_login.xml

    <com.company.app.SlidingFrameLayout>
        <ScrollView>
            <LinearLayout>
                <TextView />
                <Button />
                <android.support.design.widget.TextInputLayout>
                    <EditText />
                </android.support.design.widget.TextInputLayout>
                <android.support.design.widget.TextInputLayout>
                    <EditText />
                </android.support.design.widget.TextInputLayout>
                <Button />
                <Button />
            </LinearLayout>
        </ScrollView>
    </com.company.app.SlidingFrameLayout>
    

    fragment_login.xml中的第70行

    Line 69    <android.support.design.widget.TextInputLayout
    Line 70    android:layout_height="wrap_content"
    Line 71    android:layout_width="match_parent"
    Line 72     >
    Line 73     <EditText
    Line 74        android:id="@+id/password"
    Line 75        android:hint="@string/prompt_password"
    Line 76        android:imeOptions="actionDone"
    Line 77        android:inputType="textPassword"
    Line 78        android:layout_height="wrap_content"
    Line 79        android:layout_width="match_parent"
    Line 80        android:maxLines="1"
    Line 71        android:singleLine="true"
    Line 82        android:textSize="16sp"
    Line 83
    Line 84        />
    Line 85
    Line 86    </android.support.design.widget.TextInputLayout>
    

    LoginFragment.java

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView           = inflater.inflate(R.layout.fragment_login, container, false);
    
        mPasswordView           = (EditText)rootView.findViewById(R.id.password);
        Button registerButton   = (Button)rootView.findViewById(R.id.register_button);
        TextView registerLabel  = (TextView)rootView.findViewById(R.id.register_label);
        mSignInButton           = (Button)rootView.findViewById(R.id.sign_in_button);
        mUserNameView           = (EditText)rootView.findViewById(R.id.user_name);
        LoginActivity activity  = (LoginActivity)getActivity();
        activity.setLoginFragment(this);
    
        checkIfComplete();
    
        mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {
                if (id == EditorInfo.IME_ACTION_DONE || id == EditorInfo.IME_NULL) {
                    if (mComplete) {
                        beginLogin();
                        return true;
                    }
                }
                return false;
            }
        });
        mPasswordView.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                checkIfComplete();
            }
            @Override
            public void afterTextChanged(Editable s) {}
        });
    
        registerButton.setBackgroundColor(ContextCompat.getColor(getActivity(), R.color.colorPrimaryDark));
        registerButton.setTextColor(ContextCompat.getColor(getActivity(), R.color.colorTextEnabled));
        registerButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                EnterCodesFragment fragment = new EnterCodesFragment();
                getFragmentManager()
                        .beginTransaction()
                        .setCustomAnimations(R.animator.slide_in_from_right, R.animator.slide_out_to_left, R.animator.slide_in_from_left, R.animator.slide_out_to_right)
                        .replace(R.id.container, fragment, getString(R.string.basic_information_title_string))
                        .addToBackStack(getString(R.string.enter_codes_fragment_title))
                        .commit();
            }
        });
    
        registerLabel.setTextColor(ContextCompat.getColor(getActivity(), R.color.colorTextDisabled));
    
        mSignInButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                beginLogin();
            }
        });
    
        Button forgotPasswordButton = (Button)rootView.findViewById(R.id.forgot_password_button);
        forgotPasswordButton.setPaintFlags(forgotPasswordButton.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
        forgotPasswordButton.setOnClickListener(new View.OnClickListener() {
            @Override
    
            public void onClick(View v) {
                final View view         = View.inflate(getActivity(), R.layout.reset_password_dialog, null);
    
                final EightyPercentDialog dialog = new EightyPercentDialog(getActivity());
                dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
                dialog.setContentView(view);
    
                final EditText emailEditText  = (EditText)view.findViewById(R.id.email_edit_text);
    
                Button cancelButton     = (Button)view.findViewById(R.id.cancel_button);
                Button okButton         = (Button)view.findViewById(R.id.ok_button);
    
                cancelButton.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        dialog.dismiss();
                    }
                });
    
                okButton.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        String email    = emailEditText.getText().toString();
                        dialog.dismiss();
                        sendPasswordResetEmail(email);
                    }
                });
    
                dialog.show();
    
            }
        });
    
        mUserNameView.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                checkIfComplete();
            }
            @Override
            public void afterTextChanged(Editable s) {}
        });
    
        return rootView;
    }
    

    我在这里查看了与InflateException相关的其他几篇帖子,但这些帖子似乎都不适用于我的情况。

    例如:

    1. This question and answer似乎突出了包命名问题,这在我的项目中不是问题。
    2. This question and answer正在处理代码行顺序不正确的问题,这在我的项目中不是问题。
    3. 我查看this question以确定我的问题是否可能与使用AppCompatActivity有关,但到目前为止我还没有看到任何有问题的内容。
    4. 所以,基本上,让我感到困惑的是我在任何一台设备上都没有这个问题,而且我不太了解Android以便在她的系统上看到任何东西(也是运行5.0.1的三星手机) ,就像我的那样)会有问题。有什么我想念的吗?如何找出实际问题是什么?

0 个答案:

没有答案