2

I saw many similar questions online, and tried several solutions. But none fixed my issue. One important thing I want to mention is that, my code works well on android Phones, it only crashes on android Tablets. I have no idea what's going on.

This is the stack:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.xxxx.xxxx.android/com.xxxx.xxxx.android.LoginScreenActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.CheckBox.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2808)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2873)
at android.app.ActivityThread.access$900(ActivityThread.java:181)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1482)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6145)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.CheckBox.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at com.xxxx.xxxx.android.LoginScreenActivity.onCreate(LoginScreenActivity.java:89)
at android.app.Activity.performCreate(Activity.java:6374)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2752)
... 10 more

This is the LoginScreenActivity:

public class LoginScreenActivity extends Activity implements OnClickListener
{
    private Context context;
    private CheckBox showPassword;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.login_screen);

        context = getApplicationContext();
        showPassword = (CheckBox)findViewById(R.id.checkbox_show_password);

        //below is line 89 of LoginScreenActivity, exception happened here.
        showPassword.setOnClickListener(new OnClickListener()
        {
          @Override
          public void onClick(View view)
          {
            //.................
          }
        });
    }
}

Here's the xml file:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

            <CheckBox
                android:id="@+id/checkbox_show_password"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Show Password"/>
    </RelativeLayout>

</ScrollView>
Carrie
  • 480
  • 3
  • 10
  • 25
  • its not duplicate because of this – Kostas Drak Mar 29 '16 at 19:22
  • 2
    Do you happen to have another layout in a `res/layout-land` folder that doesn't have that ID? That would be a reason that it is null. – OneCricketeer Mar 29 '16 at 19:27
  • most likely its the interface i guess. – Kostas Drak Mar 29 '16 at 19:27
  • I think @cricket_007 is on the right track. If you have a any other layout folders in res/ (such as "layout-sw600dp") it would absolutely explain why only tablets aren't working. – BooleanCheese Mar 29 '16 at 19:29
  • @helldawg13 Explain? How would `implements OnClickListener` cause the null pointer? – OneCricketeer Mar 29 '16 at 19:32
  • 2
    I think that's the reason.... I do have more than one layout there.... actually I have all of them. `layout-land`, `layout-xlarge`, `layout-xlarge-land`. Does it mean that I have to copy this checkbox to all the layouts? – Carrie Mar 29 '16 at 19:34
  • @cricket_007 i guess just because otherwise he would have to do showPassword.setOnClickListener(this) and do the implementation in the abstract method onClick – Kostas Drak Mar 29 '16 at 19:34
  • @helldawg13 That wouldn't cause a null pointer, though. Also, `this` wasn't used at all, and there is nothing wrong with an anonymous class. I'm convinced the problem is another layout resource that doesn't have that ID. – OneCricketeer Mar 29 '16 at 19:37
  • @YabinSong what have you tried so far? – Kostas Drak Mar 29 '16 at 19:37
  • Actually what is the point of instanciating a variable since she(cause she is a girl i suppose) could use LoginScreenActivity.this – Kostas Drak Mar 29 '16 at 19:40
  • @helldawg13 yes exactly, she could be using it with a get/set to pass into an `Asyc` or something. – Petro Mar 29 '16 at 19:42
  • Unluckly the testing tablet is dead, there's some issue on it, it takes forever to charge. So I'm waiting for it now. But I'm going to add the checkbox to other layouts, and I will try landscape view first. Hopefully it will work. – Carrie Mar 29 '16 at 19:42
  • Maybe we are all wrong and you should modify the implements View.OnClickListener and also showPassword.setOnClickListener(new View.OnClickListener) because you actually trying to set a listener to a View – Kostas Drak Mar 29 '16 at 19:42
  • @YabinSong Yes also try removing the parent layouts to see if that is causing an issue (one time a `scrollview` was not initialized properly and it could not find my `button` child) – Petro Mar 29 '16 at 19:50
  • 1
    @YabinSong I am pretty sure that `login_screen` is not the xml that you posted above. – Rod_Algonquin Mar 29 '16 at 19:51
  • 1
    Okay, I added the checkbox to layout-land, it fixed my issue on the phone that when I rotates the screen to landscape, the app crashes. I was working on both issues. Obviously both issue caused by same reason. I only have my checkbox in the layout folder. I should add it to all the layout folders xml files. – Carrie Mar 29 '16 at 19:55
  • 1
    @YabinSong If you want the app to look exactly the same on every device, you should probably delete the other layout folders. That way you only have a single layout to worry about. – BooleanCheese Mar 29 '16 at 19:59

2 Answers2

10

There are two problems that are apparent.

The obvious: NullPointerException

The solution: All instances of login_screen.xml will need a Checkbox with android:id="@+id/checkbox_show_password" in order for findViewById(R.id.checkbox_show_password) to not return null.

This is worth mentioning because in the comments it was stated that there are multiple res/layout-* folders and the error only happens on tablets, so that is important.

Second problem:

While any View can use an OnClickListener, you have a CheckBox, not a Button, so you'll probably want to know when the checkbox was checked, not just clicked.

In that case, use an OnCheckedChangeListener

showPassword.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if (isChecked){
            // do something
        }else {
            //do something else
        }
    }
});
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
3

Well with a checkbox you cannot have an onClickListener. Please remove the Interface (implements) also. You may want to try this:

showPassword.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (showPassword.isChecked()){
                    //do something
                }else {
                    //do something else
                }
            }
        });

Hope it helps!!!

Petro
  • 3,484
  • 3
  • 32
  • 59
Kostas Drak
  • 3,222
  • 6
  • 28
  • 60