Android: findViewById returns Null even if is after setContentView

做~自己de王妃 提交于 2019-11-27 08:26:24

问题


Here's my code in 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();
    }
}

in 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" />

And this is the log when i run the application:

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

The problem is that "loginButton" is NULL but i don't know why, because i call the findViewById after the setContentView!


回答1:


It seems that your Button is in fragment layout, so your on click method might be in your fragment (PlaceholderFragment) instead of your activity. You need to declare another Class extends with Fragment..

First, create a new Class named PlaceHolderFragment. Extend it with Fragment and add this code below to it:

@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.

Then, your layout activity for MainActivity (named activity_main) might have a FrameLayout with the id container like this:

<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>  

Finally, your MainActivity will only have:

@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
}



回答2:


Try declaring the button inside onCreate, rather than declaring it outside of it (which is what I'm assuming you're doing).

Oh, and if you haven't tried this already, use "VIEW.findViewById(R.id.loginButton)", rather than just "findViewById(R.id.loginButton);". I think that's more likely your problem; I forget about it a lot too.



来源:https://stackoverflow.com/questions/22591626/android-findviewbyid-returns-null-even-if-is-after-setcontentview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!