Null pointer Exception - findViewById()
Asked Answered
F

12

59

Can anyone help me to find out what can be the issue with this program. In the onCreate() method the findViewById() returns null for all ids and this causes a null pointer exception later. I can not figure out why the findViewById() can not find the view. Any suggestions?

This is the main code:

public class MainActivity extends Activity {

    ViewPager pager;
    MyPagerAdapter adapter;
    LinearLayout layout1, layout2, layout3;

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

        layout1 = (LinearLayout) findViewById(R.id.first_View);
        layout2 = (LinearLayout) findViewById(R.id.second_View);
        layout3 = (LinearLayout) findViewById(R.id.third_View);

        adapter = new MyPagerAdapter();
        pager = (ViewPager) findViewById(R.id.main_pager);
        pager.setAdapter(adapter);
    }

    private class MyPagerAdapter extends PagerAdapter
    {

        @Override
        public int getCount() { 
            return 3;
        }

        @Override
        public Object instantiateItem(ViewGroup collection, int position) {

            LinearLayout l = null;

            if (position == 0 )
            {
                l = layout1;
            }
            if (position == 1)
            {
                l = layout2;
            }

            if (position == 2)
            {
                l = layout3;
            }
                collection.addView(l, position);
                return l;
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return (view==object);
        }

         @Override
         public void destroyItem(ViewGroup collection, int position, Object view) {
                 collection.removeView((View) view);
         }
    }
}

And the related XML files:

activity_main layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:orientation="vertical"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:background="#a4c639">


    <android.support.v4.view.ViewPager
                        android:layout_width="match_parent" 
                        android:layout_height="match_parent" 
                        android:id="@+id/main_pager"/>
</LinearLayout>

activity_first layout:

<?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:id="@+id/first_View">

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/hello_world" />

<Button
    android:id="@+id/button1"
    style="?android:attr/buttonStyleSmall"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Button" />

</LinearLayout>

activity_second layout:

 <?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:id="@+id/second_View">

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/hello_world" />

</LinearLayout>

And the activity_third layout:

<?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:id="@+id/third_View">

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/hello_world" />

</LinearLayout>
Fusspot answered 29/9, 2013 at 13:16 Comment(0)
M
92

findViewById() returns a View if it exists in the layout you provided in setContentView(), otherwise it returns null and that's what happening to you. Note that if you don't setContentView(), and don't have a valid view to findViewById() on, findViewById() will always return null until you call setContentView().

This also means variables in the top-level trigger an NPE, because they're called before onCreate(), and by extension, before setContentView(). See also the activity lifecycle

Example if you setContentView(R.layout.activity_first); and then call findViewById(R.id.first_View); it will return a View which is your layout.

But if you call findViewById(R.id.second_View); before setContentView(), it will return null since there is not a view in your activity_first.xml layout called @+id/second_View.

Muro answered 29/9, 2013 at 13:21 Comment(4)
I have included all layouts to the main layout and I have no null pointer exception anymore. Thanks for the tip.Fusspot
When I used this on a different view other than the currently displaying view, that one appeared. To get over with that unwanted behavior, I referred the view without using setContentView as follows. layout1 = (LinearLayout) View.inflate(this, R.layout.first_View, null); Then to access anything inside it, I could use Button botton = (Button) layout1.findViewById(R.id.button1); Just adding so that it might be helpful to sombody.Sharecropper
Why? What is the advantage of forcing us?Suiting
Then what's the solution to include the resource which is not provided insetContentView().Bombard
B
3

Emphasis added

For those cases within an Activity class.

Activity.findViewById(int id)

Finds a view that was identified by the id attribute from the XML that was processed in onCreate(Bundle).


Otherwise, such as an Fragment, Adapter, a View from a LayoutInflater, etc.

View.findViewById(int id)

Look for a child view with the given id. If this view has the given id, return this view.


Either case,

Returns
The view if found or null otherwise.


Now, re-check your XML files. Make sure you put the right value into setContentView or inflater.inflate.

In the case of an Activity, call findViewById after setContentView.

Then, make sure there is a View you are looking for with android:id="@+id/..." in that layout. Make sure the + is at @+id, which will add the resource to the R.id values to ensure you can find it from Java.

Beecham answered 29/9, 2013 at 13:16 Comment(0)
H
2

The views you're trying to get are not defined in your activity_main layout. You need to programmatically inflate the views you're trying to add to the pager.-

@Override
public Object instantiateItem(ViewGroup collection, int position) {
    LinearLayout l = null;

    if (position == 0) {
        l = (LinearLayout) View.inflate(this, R.layout.activity_first, null);
    }
    if (position == 1) {
        l = (LinearLayout) View.inflate(this, R.layout.activity_second, null);
    }
    if (position == 2) {
        l = (LinearLayout) View.inflate(this, R.layout.activity_third, null);
    }

    collection.addView(l, position);
    return l;
}
Haiti answered 29/9, 2013 at 13:25 Comment(1)
How would you access the views in your mainactivity?Quirinus
D
2

Sometimes you need clean your project in Eclipse (Project - Clean..).

Dallapiccola answered 5/4, 2014 at 17:13 Comment(1)
that solved it for me - it's ridiculous that it's a manual step, and also that bugs compromise the id lookups. . I thought machines are always logical - what on Earth can compromise the code in such a way?!Pinguid
F
1

add those views to the pager adapter before accessing them.

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

    adapter = new MyPagerAdapter();
    pager = (ViewPager) findViewById(R.id.main_pager);
    pager.setAdapter(adapter);

    layout1 = (LinearLayout) findViewById(R.id.first_View);
    layout2 = (LinearLayout) findViewById(R.id.second_View);
    layout3 = (LinearLayout) findViewById(R.id.third_View);

}

in the pager adapter:

public Object instantiateItem(View collection, int position) {
    if(position == 0){
        View layout = inflater.inflate(R.layout.activity_first, null);

        ((ViewPager) collection).addView(layout);

        return layout;
    } 
    ... and so forth.

}

from here you can access them via findViewById.

Fondafondant answered 29/9, 2013 at 13:28 Comment(0)
V
1

In my case, it was a stupid mistake on my part. I had written code in the OnCreate method but it was above the setContentView line of code. Once I moved my code below this line the application started working fine.

setContentView(R.layout.activity_main);
Valvulitis answered 8/5, 2018 at 16:37 Comment(0)
B
0

What @Warlock said above is right , you should initial LinearLayout layout1, layout2, layout3 by the right way:

LinearLayout layout1 = (LinearLayout) View.inflate(this, R.layout.first_View, null);
LinearLayout layout2 = (LinearLayout) View.inflate(this, R.layout.second_View, null);
LinearLayout layout3 = (LinearLayout) View.inflate(this, R.layout.third, null);

wish my advise help you

Billi answered 29/9, 2013 at 13:29 Comment(0)
M
0

In Android, findViewById(R.id.some_id) works when you are finding view in the layout set.

That is, if you have set a layout say:

setContentView(R.layout.my_layout);

Views can be found only in this layout (my_layout).

In your code layout1, layout2, layout3 all are three different layouts and they are not set to the activity.

Maestas answered 29/9, 2013 at 13:34 Comment(0)
R
0

The findViewById method must find what is in the layout (which you called in the setContentView)

Regardant answered 29/9, 2013 at 13:59 Comment(0)
L
0

I have gotten this error today and it was so simple to clear, that I "facepalmed".

Just try to add the UI element to your layout xml File in your res/layout-port directory!!!

Lotus answered 26/5, 2014 at 9:51 Comment(0)
M
0

Use the adaptor, to inflate the layout, and based on the position you can search for the view.

override fun instantiateItem(collection: ViewGroup, position: Int) : ViewGroup {
    val inflater = LayoutInflater.from(mContext)
    val layout = inflater.inflate(mData[position], collection, false) as ViewGroup

    if(position == your_position) {
       val nameOfField: TextView = layout.findViewById(R.id.item_id)
    }
Manipulate answered 12/11, 2021 at 17:30 Comment(0)
M
-1

This problem is also generated when you are having same name of many components in XML file. Even if they are different layout files you should give every element a unique name. This error occur because you are having a XML element with the same name in another layout file and android studio is trying to access that and showing this error

Mechling answered 1/6, 2021 at 18:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.