0

In chapter 3 of Big Nerd Ranch guide, they explain how to differently layout the default and landscape views. But when I create an Android Resource Directory with Landscape orientation and then copy the same .xml from the default layout into the /layout-land and make changes into the latter, the app crashes on my physical device when I rotate to landscape mode.

If I don't change anything in the copied .xml inside the /layout-land file, it runs absolutely fine when rotated.

activity.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    >

    <TextView
        android:id="@+id/question_text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="24dp" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/true_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/true_button"/>

        <Button
            android:id="@+id/false_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/false_button"/>

    </LinearLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        >

        <Button
            android:id="@+id/prev_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/prev_button"/>

        <Button
            android:id="@+id/next_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/next_button"/>
    </LinearLayout>



</LinearLayout>

/layout-land/activity.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    >

    <TextView
        android:id="@+id/question_text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="24dp" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/true_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/true_button"/>

        <Button
            android:id="@+id/false_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/false_button"/>

    </LinearLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        >

        <Button
            android:id="@+id/prev_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/prev_button"/>

    </LinearLayout>



</LinearLayout>

Logcat

FATAL EXCEPTION: main
                                                                             Process: com.bignerdranch.android.geoquiz, PID: 5727
                                                                             java.lang.RuntimeException: Unable to start activity ComponentInfo{com.bignerdranch.android.geoquiz/com.bignerdranch.android.geoquiz.QuizActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
                                                                                    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2695)
                                                                                    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2769)
                                                                                    at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4378)
                                                                                    at android.app.ActivityThread.access$1000(ActivityThread.java:177)
                                                                                    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1436)
                                                                                    at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                    at android.os.Looper.loop(Looper.java:135)
                                                                                    at android.app.ActivityThread.main(ActivityThread.java:5910)
                                                                                    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:1405)
                                                                                    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200)
                                                                                 Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
                                                                                    at com.bignerdranch.android.geoquiz.QuizActivity.onCreate(QuizActivity.java:81)
                                                                                    at android.app.Activity.performCreate(Activity.java:6178)
                                                                                    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
                                                                                    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2648)
                                                                                    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2769) 
                                                                                    at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4378) 
                                                                                    at android.app.ActivityThread.access$1000(ActivityThread.java:177) 
                                                                                    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1436) 
                                                                                    at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                                    at android.os.Looper.loop(Looper.java:135) 
                                                                                    at android.app.ActivityThread.main(ActivityThread.java:5910) 
                                                                                    at java.lang.reflect.Method.invoke(Native Method) 
                                                                                    at java.lang.reflect.Method.invoke(Method.java:372)

Cannot figure out what is the problem. Please help

Chaki
  • 25
  • 1
  • 5
  • Post your logcat or you will be probably able to figure out from it yourself – Alexander Kulyakhtin Mar 27 '16 at 08:45
  • 1
    we cannot figure out, untill you post stacktrace ! – Shree Krishna Mar 27 '16 at 08:45
  • Your landscape layout is missing the `next_button` `Button`. If you're using `findViewById()` to get a reference to it, it will return null, and calling any methods on it will result in a `NullPointerException`. – Mike M. Mar 27 '16 at 08:49
  • @MikeM. it is returning a NullPointerException. But isn't the point of having a separate file for the landscape so that you could have a different layout ? – Chaki Mar 27 '16 at 08:58
  • 1
    Sure, but your code has to account for the different layout, too. You can't still try to use the `next_button` if it isn't there in landscape mode. – Mike M. Mar 27 '16 at 09:01
  • Funny since the book doesn't account for this. Furthermore, the book also says, "Rotate the device to landscape to see the new layout (Figure 3.12). Of course, this is not just a new layout – it is a new QuizActivity as well" - "QuizActivity" being the .java file for this example. – Chaki Mar 27 '16 at 09:07
  • If that's the only thing that's different between portrait and landscape, just check if it's null before you call `setOnClickListener()` on it. Of course, be sure you're not trying to call methods on it elsewhere, then, too. – Mike M. Mar 27 '16 at 09:15
  • 1
    Wasn't really necessary, since we already figured out the problem. – Mike M. Mar 27 '16 at 09:19

1 Answers1

0

You can have different layout files that appear different, but if you are using findViewById on views that do not exist (such as the next button), then you'll get a NullPointerException when you go to call any methods on that view (such as assign it's click listener, in the case of your error).

The simple solution is to keep all the views in both layouts with the same ids, but just rearrange them according to the orientation.

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245