使用onCreateView的片段会导致异常

时间:2015-03-25 19:05:33

标签: android android-fragments

当我尝试访问片段中的textviews时,它会抛出nullpointer异常。在onCreateView夸大后,我已经声明了变量并在View中对其进行了初始化。我不知道为什么会抛出错误。

这是我的代码

public class LoginTextHolder extends Fragment {

private View view;
EditText txtUsername;
EditText txtPassword;

public static LoginTextHolder newInstance() {

    return new LoginTextHolder();
}

public LoginTextHolder() {
    // Required empty public constructor
}

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

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    view = inflater.inflate(R.layout.fragment_login_text_holder, container, false);
    txtUsername = (EditText) view.findViewById(R.id.txtUserName);
    txtPassword = (EditText) view.findViewById(R.id.txtPassword);
    return view;
}


@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);

}

@Override
public void onDetach() {
    super.onDetach();
}

public String[] giveData() {
    String[] uNp = {"", ""};
    uNp[0] = txtUsername.getText().toString();
    uNp[1] = txtPassword.getText().toString();
    return uNp;
}
}

这是我的logcat输出

FATAL EXCEPTION: main
java.lang.NullPointerException
        at akshara.homeshop.fragments.LoginTextHolder.giveData(LoginTextHolder.java:65)
        at akshara.homeshop.activities.LoginActivity.onLoginEventFragmentInteraction(LoginActivity.java:51)
        at akshara.homeshop.fragments.LoginEventHandlers.onClick(LoginEventHandlers.java:76)
        at android.view.View.performClick(View.java:4204)
        at android.view.View$PerformClick.run(View.java:17355)
        at android.os.Handler.handleCallback(Handler.java:725)
        at android.os.Handler.dispatchMessage(Handler.java:92)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:5041)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
        at dalvik.system.NativeStart.main(Native Method)

我该如何解决这个问题?

这是我的登录活动:

public class LoginActivity extends FragmentActivity implements LoginEventHandlers.LoginEventFragmentInteractionListener {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);
}

@Override
public void onLoginEventFragmentInteraction(View view) {
    switch (view.getId()) {
        case R.id.btnSignIn:
            LoginTextHolder loginTextsFragment = LoginTextHolder.newInstance();

            Log.e("Sony", loginTextsFragment.giveData()[0]);
            Log.e("Sony", loginTextsFragment.giveData()[1]);
            break;
        case R.id.lblSignUp:
            Log.e("Sony", "SignUp");
            break;
    }

}

}

这是片段布局

<RelativeLayout
android:id="@+id/loginTextHolderRoot"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:padding="@dimen/holderDefaultPadding"
tools:context="akshara.homeshop.fragments.LoginTextHolder">


<EditText
    android:id="@+id/txtUserName"
    style="@style/MyDefaultTextBoxStyle"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="@dimen/defaultWidgetTopMargin"
    android:hint="@string/userName"/>

<EditText
    android:id="@+id/txtPassword"
    style="@style/MyDefaultTextBoxStyle"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/txtUserName"
    android:layout_marginTop="@dimen/defaultWidgetTopMargin"
    android:hint="@string/password"
    android:inputType="textPassword"/>
</RelativeLayout>

第一张图片来自onCreateView,下一张图片来自giveData

from give data![][1]

Image

4 个答案:

答案 0 :(得分:2)

查看您的堆栈跟踪,看起来您很快就会调用giveData。你初始化

EditText txtUsername;
EditText txtPassword;
在您的片段中

,但是在片段准备好之前,您似乎在loginActivity中使用了该函数。通常,您也应该执行空值检查。

答案 1 :(得分:1)

首先,我喜欢你的帖子,充满了信息。现在应该删除帖子的-1值。

我认为txtUsername(来自giveData())为null,因为您在方法newInstance中返回一个新片段。并且新片段没有对UI的引用。它需要正确的Context中的当前片段。试试这个:

public static LoginTextHolder newInstance() {

    return this;    // return current instance of this fragment
}

但通常您不需要使用空参数指定newInstance。功能强大的 FragmentManager 可以在上下文中检索当前的Fragment。它有助于您的代码在FragmentActivity中。

与此同时,让我们先尝试一下。

答案 2 :(得分:1)

将初始化移至onActivityCreated(Bundle savedInstanceState)。在onCreateView()总是来自onActivityCreated(Bundle savedInstanceState)的电话中调用片段中的控件是不安全的,谢谢大家的时间

答案 3 :(得分:1)

有一个很好的Google链接@ SlidingTabsBasicFragment.java,显示了与此帖中提出的问题相关的良好示例代码。

网页上的代码段:

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

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        // Get the ViewPager and set it's PagerAdapter so that it can display items
        mViewPager = (ViewPager) view.findViewById(R.id.viewpager);
        mViewPager.setAdapter(new SamplePagerAdapter());

        // Give the SlidingTabLayout the ViewPager, this must be done AFTER the ViewPager has had
        // it's PagerAdapter set.
        mSlidingTabLayout = (SlidingTabLayout) view.findViewById(R.id.sliding_tabs);
        mSlidingTabLayout.setViewPager(mViewPager);
    }

注意:

  1. 在覆盖onCreateView时,它只返回inflater.inflate中的视图(......,仅此而已。
  2. 在覆盖onViewCreated时,它会创建/查找UI,并且它会执行更多操作。此方法在onCreateView之后立即发生。在这个案例中,从发布的问题来看,时机有所不同。
  3. 根据onViewCreated method,来自Google的部分解释是:
  4.   

    这使得子类有机会在知道后初始化自己   他们的视图层次结构已经完全创建。

    所以现在我知道并且会记住...