Android:findViewById即使在setContentView之后也返回Null

时间:2014-03-23 13:38:06

标签: android null oncreate findviewbyid

这是我在LoginActivity中的代码:

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

    if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction()
                .add(R.id.container, new PlaceholderFragment()).commit();
    }

    loginButton = (Button)findViewById(R.id.loginButton);

    loginButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            onLoginButtonClicked();
        }
    });

    // Check if there is a currently logged in user
    // and they are linked to a Facebook account.
    ParseUser currentUser = ParseUser.getCurrentUser();
    if ((currentUser != null) && ParseFacebookUtils.isLinked(currentUser)) {
        // Go to the main activity
        showHomeActivity();
    }
}

在fragment_login.xml

<Button
    android:id="@+id/loginButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:text="@string/login_button" />

这是我运行应用程序时的日志:

E/AndroidRuntime(6647): FATAL EXCEPTION: main
E/AndroidRuntime(6647): Process: com.moostachestudio.drinkitapp, PID: 6647
E/AndroidRuntime(6647): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.moostachestudio.drinkitapp/com.moostachestudio.drinkitapp.LoginActivity}: java.lang.NullPointerException
E/AndroidRuntime(6647):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
E/AndroidRuntime(6647):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
E/AndroidRuntime(6647):     at android.app.ActivityThread.access$800(ActivityThread.java:135)
E/AndroidRuntime(6647):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
E/AndroidRuntime(6647):     at android.os.Handler.dispatchMessage(Handler.java:102)
E/AndroidRuntime(6647):     at android.os.Looper.loop(Looper.java:136)
E/AndroidRuntime(6647):     at android.app.ActivityThread.main(ActivityThread.java:5017)
E/AndroidRuntime(6647):     at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(6647):     at java.lang.reflect.Method.invoke(Method.java:515)
E/AndroidRuntime(6647):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
E/AndroidRuntime(6647):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
E/AndroidRuntime(6647):     at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime(6647): Caused by: java.lang.NullPointerException
E/AndroidRuntime(6647):     at com.moostachestudio.drinkitapp.LoginActivity.onCreate(LoginActivity.java:45)
E/AndroidRuntime(6647):     at android.app.Activity.performCreate(Activity.java:5231)
E/AndroidRuntime(6647):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
E/AndroidRuntime(6647):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
E/AndroidRuntime(6647):     ... 11 more

问题在于&#34; loginButton&#34;是NULL但我不知道为什么,因为我在setContentView之后调用了findViewById!

2 个答案:

答案 0 :(得分:2)

您的Button似乎处于片段布局中,因此您的点击方法可能位于您的片段中PlaceholderFragment),而不是您的活动。你需要声明另一个使用Fragment扩展的类..

首先,创建一个名为PlaceHolderFragment的新类。使用Fragment进行扩展,并将以下代码添加到其中:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
    Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_login, container, false);
    // ...
    loginButton = (Button) rootView.findViewById(R.id.loginButton);
    loginButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            onLoginButtonClicked();
        }
    });
    // ...
    return rootView;
}  

// put your method onLoginButtonClicked here.

然后,MainActivity(名为activity_main)的布局活动可能包含FrameLayout ID容器,如下所示:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <!-- other views -->

</FrameLayout>  

最后,您的MainActivity只会:

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

    if (savedInstanceState == null) {
        // you add you fragment here in id container
        getSupportFragmentManager().beginTransaction()
             .add(R.id.container, new PlaceholderFragment()).commit();
    }

    // ... without loginButton
    // and some more stuff
}

答案 1 :(得分:0)

尝试在onCreate中声明按钮,而不是在它之外声明它(这就是我假设你正在做的事情)。

哦,如果你还没有尝试过,请使用“VIEW.findViewById(R.id.loginButton)”,而不仅仅是“findViewById(R.id.loginButton);”。我认为这更可能是你的问题;我也忘了它。