0

I am trying to learn building Android apps. I am reading the book "Android 5 Programming by Example" and trying sample codes from there. However I have problem with "CardView with Layout" chapter. First, I can not arrange my pictures and text like samples in the book, especially in landscape view - i can't move text to the right of the picture. Second thing is, I have an exception when I click on the images. Problem is in DetailActivity.class file and line "detailText.setMovementMethod (new ScrollingMovementMethod());". I get these errors:

FATAL EXCEPTION: main Process: com.example.rado.ancientbritain, PID: 10017 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.rado.ancientbritain/com.example.rado.ancientbritain.DetailActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setMovementMethod(android.text.method.MovementMethod)' on a null object reference at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387) at android.app.ActivityThread.access$800(ActivityThread.java:151) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5254) 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:903) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setMovementMethod(android.text.method.MovementMethod)' on a null object reference at com.example.rado.ancientbritain.DetailActivity.onCreate(DetailActivity.java:30) at android.app.Activity.performCreate(Activity.java:5990) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)  at android.app.ActivityThread.access$800(ActivityThread.java:151)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)  at android.os.Handler.dispatchMessage(Handler.java:102)  at android.os.Looper.loop(Looper.java:135)  at android.app.ActivityThread.main(ActivityThread.java:5254)  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:903)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) 

My files:
1. DetailActivity

    package com.example.rado.ancientbritain;

    import android.content.Intent;
    import android.net.Uri;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.text.method.ScrollingMovementMethod;
    import android.view.View;
    import android.widget.ImageView;
    import android.widget.TextView;

    import java.util.ArrayList;
    import java.util.Random;

    public class DetailActivity extends AppCompatActivity {
        private ImageView detailImage;
        private ArrayList<MainDataDef> detailData;



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

            detailImage = (ImageView) findViewById(R.id.detail_image);
            TextView detailName = (TextView) findViewById(R.id.detail_name);
            TextView detailDistance = (TextView) findViewById(R.id.detail_distance);
            TextView detailText = (TextView) findViewById(R.id.detail_text);

            detailText.setMovementMethod (new ScrollingMovementMethod());

            ImageView detailWebLink = (ImageView) findViewById(R.id.detail_web_link);

            setContentView(R.layout.activity_detail);
            int i = MainActivity.currentItem;
            Random n = new Random();
            int m = n.nextInt((600 - 20) + 1) + 20;
            setTitle(getString(R.string.app_name) + " - " + MainData.
                    nameArray[i]);
            detailImage.setImageResource(MainData.detailImageArray[i]);
            detailName.setText(MainData.nameArray[i]);
            detailDistance.setText(String.valueOf(m) + " miles");
            detailText.setText(MainData.detailTextArray[i]);

            detailWebLink.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent();
                    intent.setAction(Intent.ACTION_VIEW);
                    intent.addCategory(Intent.CATEGORY_BROWSABLE);
                    intent.setData(Uri.parse(
                            MainData.detailWebLink[MainActivity.currentItem]));
                    startActivity(intent);
                }
            });
        }
    }
  1. MainActivity

    package com.example.rado.ancientbritain;
    
    import android.content.Context;
    import android.content.Intent;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.support.v7.widget.LinearLayoutManager;
    import android.support.v7.widget.RecyclerView;
    import android.view.View;
    
    import java.util.ArrayList;
    
    public class MainActivity extends AppCompatActivity {
    
        private RecyclerView recyclerView;
        public static int currentItem;
        static View.OnClickListener mainOnClickListener;
    
        private class MainOnClickListener implements View.OnClickListener {
            private final Context context;
    
            private MainOnClickListener(Context c) {
                this.context = c;
            }
    
            @Override
            public void onClick(View v) {
                currentItem = recyclerView.getChildAdapterPosition(v);
                startActivity(new Intent(getApplicationContext(),
                        DetailActivity.class));
            }
        }
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            recyclerView = (RecyclerView) findViewById(R.id.main_recycler_view);
            recyclerView.setHasFixedSize(true);
            mainOnClickListener = new MainOnClickListener(this);
    
            RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
            recyclerView.setLayoutManager(layoutManager);
    
            ArrayList<MainDataDef> mainData = new ArrayList<MainDataDef>();
            for (int i = 0; i < MainData.nameArray.length; i++) {
                mainData.add(new MainDataDef(
                        MainData.imageArray[i],
                        MainData.nameArray[i],
                        MainData.infoArray[i]
                ));
            }
    
            RecyclerView.Adapter adapter = new MainAdapter(mainData);
            recyclerView.setAdapter(adapter);
        }
    }
    
  2. MainAdapter

    package com.example.rado.ancientbritain;
    
    import android.support.v7.widget.RecyclerView;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ImageView;
    import android.widget.TextView;
    
    import java.util.ArrayList;
    
    /**
     * Created by Rado on 7.9.2017 г..
     */
    
    public class MainAdapter extends RecyclerView.Adapter<MainAdapter.MainViewHolder> {
        private ArrayList<MainDataDef> mainData;
    
        public MainAdapter(ArrayList<MainDataDef> a) {
            this.mainData = a;
        }
    
        @Override
        public MainViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View v = LayoutInflater.from(parent.getContext()).inflate(
                    R.layout.card_main, parent, false);
            v.setOnClickListener(MainActivity.mainOnClickListener);
    
            return new MainViewHolder(v);
        }
    
        @Override
        public void onBindViewHolder(final MainViewHolder holder, final int position) {
            ImageView imageIcon = holder.imageIcon;
            TextView textName = holder.textName;
            TextView textInfo = holder.textInfo;
    
            imageIcon.setImageResource(mainData.get(position).getImage());
            textName.setText(mainData.get(position).getName());
            textInfo.setText(mainData.get(position).getInfo());
        }
    
        @Override
        public int getItemCount() {
            return mainData.size();
        }
    
        public static class MainViewHolder extends RecyclerView.ViewHolder {
            ImageView imageIcon;
            TextView textName;
            TextView textInfo;
    
            public MainViewHolder(View v) {
                super(v);
                this.imageIcon = (ImageView) v.findViewById(R.id.card_image);
                this.textName = (TextView) v.findViewById(R.id.card_name);
                this.textInfo = (TextView) v.findViewById(R.id.card_info);
            }
        }
    }
    
  3. MainData

    package com.example.rado.ancientbritain;
    
    /**
     * Created by Rado on 7.9.2017 г..
     */
    
    public class MainData {
        static Integer[] imageArray = {R.drawable.henge_icon,
        R.drawable.horse_icon, R.drawable.wall_icon,
        R.drawable.skara_brae_icon, R.drawable.tower_icon};
    
        static String[] nameArray = {"Stonehenge",
        "Uffington White Horse", "Hadrian's wall",
        "Skara Brae", "Tower of London"};
    
        static String[] infoArray = {"Aylsbury, Wiltshire",
                "Uffington, Oxfordshire", "Cumbria - Durham",
                "Mainland, Orkney", "Tower Hamlets, London"};
        static Integer[] detailImageArray =
                {R.drawable.henge_large, R.drawable.horse_large,
                        R.drawable.wall_large, R.drawable.skara_brae_large,
                        R.drawable.tower_large};
        static Integer[] detailTextArray =
                {R.string.detail_text_henge,
                        R.string.detail_text_horse, R.string.detail_text_wall,
                        R.string.detail_text_skara,
                        R.string.detail_text_tower};
        static String[] detailWebLink =
                {"https://en.wikipedia.org/wiki/Stonehenge",
                        "https://en.wikipedia.org/wiki/Uffington_White_Horse",
                        "https://en.wikipedia.org/wiki/Hadrian%27s_Wall",
                        "https://en.wikipedia.org/wiki/Skara_Brae",
                        "https://en.wikipedia.org/wiki/Tower_of_London"};
    }
    
  4. MainDataDef

    package com.example.rado.ancientbritain;
    
    /**
     * Created by Rado on 7.9.2017 г..
     */
    
    public class MainDataDef {
        int image;
        String name;
        String info;
    
        public MainDataDef(int image, String name, String info) {
            this.image = image;
            this.name = name;
            this.info = info;
        }
    
        public int getImage() { return image; }
    
        public String getName() { return name; }
    
        public String getInfo() { return info; }
    }
    

Layout 1. activty_detail.xml

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

    <ImageView
        android:id="@+id/detail_image"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_gravity="center_horizontal"
        android:layout_weight="3"
        app:srcCompat="@drawable/wall_large" />

    <TextView
        android:id="@+id/detail_name"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="Name" />

    <TextView
        android:id="@+id/detail_distance"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="Distance" />

    <TextView
        android:id="@+id/detail_text"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:gravity="center"
        android:layout_weight="2"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:maxLines = "100"
        android:scrollbars = "vertical"
        android:text="Text" />

    <ImageView
        android:id="@+id/detail_web_link"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="right"
        app:srcCompat="@drawable/web_icon" />

</LinearLayout>
  1. activity_main.xml

    <android.support.v7.widget.RecyclerView
        android:id="@+id/main_recycler_view"
        android:layout_width="368dp"
        android:layout_height="495dp"
        tools:layout_editor_absoluteY="8dp"
        tools:layout_editor_absoluteX="8dp" /> />
    

  2. card_main.xml

    <android.support.v7.widget.CardView
        android:id="@+id/card_view"
        android:layout_width="match_parent"
        android:layout_height="100dp" >
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
    
            <ImageView
                android:id="@+id/card_image"
                android:layout_width="0dp"
                android:layout_weight="2"
                app:srcCompat="@mipmap/ic_launcher"
                android:contentDescription=""
                android:layout_height="match_parent" />
    
            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="5"
                android:orientation="vertical">
    
                <TextView
                    android:id="@+id/card_name"
                    android:textAppearance="?android:attr/textAppearanceLarge"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:text="card_name" />
    
                <TextView
                    android:id="@+id/card_info"
                    android:textAppearance="?android:attr/textAppearanceSmall"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:text="card_info" />
    
            </LinearLayout>
    
        </LinearLayout>
    </android.support.v7.widget.CardView>
    

Layout-landscape activity_detail.xml

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

    <ImageView
        android:id="@+id/detail_image"
        android:layout_width="286dp"
        android:layout_height="213dp"
        android:layout_weight="0.5"
        android:layout_gravity="center_vertical"
        app:srcCompat="@drawable/wall_large" />

    <TextView
        android:id="@+id/detail_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="Name"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <TextView
        android:id="@+id/detail_distance"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars = "vertical"
        android:gravity="center"
        android:text="Distance" />

    <TextView
        android:id="@+id/detail_text"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="2"
        android:layout_gravity="left"
        android:layout_marginLeft="8dp"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:maxLines = "100"
        android:scrollbars = "vertical"
        android:text="Text" />

    <ImageView
        android:id="@+id/detail_web_link"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="right"
        app:srcCompat="@drawable/web_icon" />

</LinearLayout>

and build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    buildToolsVersion "26.0.1"
    defaultConfig {
        applicationId "com.example.rado.ancientbritain"
        minSdkVersion 21
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:cardview-v7:26.0.+'
    compile 'com.android.support:recyclerview-v7:26.0.+'
    compile 'com.android.support:appcompat-v7:26.+'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'
}
Shivam Kumar
  • 1,892
  • 2
  • 21
  • 33
Rado
  • 39
  • 1
  • 9
  • 1
    You have to call `setContentView()` _before_ any calls to `findViewById()`. Also, that is _waaay_ more code than is necessary. Please post only the code needed to demonstrate the issue, and always include the complete stack trace from the crash. – Mike M. Sep 07 '17 at 19:36
  • Yes, but I am very new to Android, and I am following the book. Tried putting setContentView() with different layouts as you suggested before findViewById() but the problem still remains when I click. Which code should I post? If I don't post all thing you wouldn't be able to test the project. Also what could be the problem with text positioning beside pictures in landscape? – Rado Sep 07 '17 at 20:00
  • One question per post, please. Also, you need to create [mcve]s for your singular issues. We aren't supposed to debug your entire project in one shot. You need to pare down your code and layouts to the minimum to demonstrate one problem per question. The second link in the banner at the top of your question shows how to go about fixing a `NullPointerException`. If you're getting one now when you click a link, you should follow the advice there, and try to determine the exact cause. – Mike M. Sep 07 '17 at 20:09
  • Forget it, just delete the post, I won't get solution here as I see even to the main question. I will try another book, this has problems. – Rado Sep 07 '17 at 20:33
  • I just reread your comment. I didn't suggest "different layouts". Simply move the `setContentView(R.layout.activity_detail);` line in `DetailActivity` to right after the `super.onCreate(savedInstanceState);` line. That will take care of the `NullPointerException` you've shown above. – Mike M. Sep 07 '17 at 20:33
  • As for your layout, if you mean you want the text to the side of the image, then you just need to change your layout. You're using a vertical `LinearLayout` there, which will just stack all of the `View`s on top of each other. There are many different ways to do layouts, so you'll just have to play around until you get familiar with them. – Mike M. Sep 07 '17 at 20:39
  • Also, if you want this question deleted, you can do it. There's a delete link under your question, below the tags, to the left. – Mike M. Sep 07 '17 at 20:41
  • Perfect, this worked! :) – Rado Sep 08 '17 at 06:55

0 Answers0