Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android ViewPager findViewById not working - Always returning null

public class HSPTabletTestActivity extends Activity {
private class MyPagerAdapter extends PagerAdapter {

    public int getCount() {
        return 2;
    }

    public Object instantiateItem(View collection, int position) {

        LayoutInflater inflater = (LayoutInflater) collection.getContext()
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        int resId = 0;
        switch (position) {
        case 0:
            resId = R.layout.lighttab;
            break;
        case 1:
            resId = R.layout.securitytab;
            break;
        }

        View view = inflater.inflate(resId, null);

        ((ViewPager) collection).addView(view, 0);
        return view;
    }

    @Override
    public void destroyItem(View arg0, int arg1, Object arg2) {
        ((ViewPager) arg0).removeView((View) arg2);

    }

    @Override
    public void finishUpdate(View arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public boolean isViewFromObject(View arg0, Object arg1) {
        return arg0 == ((View) arg1);

    }

    @Override
    public void restoreState(Parcelable arg0, ClassLoader arg1) {
        // TODO Auto-generated method stub

    }

    @Override
    public Parcelable saveState() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void startUpdate(View arg0) {
        // TODO Auto-generated method stub

    }

}

I have this code up there ^^ ... Pretty much taken directly from http://mobile.tutsplus.com/tutorials/android/android-user-interface-design-horizontal-view-paging/ ... I'm still pretty new in the world of android developement :/

Now I'm trying to access a spinner control and some buttons inside the "pages". But findViewById keeps returning null!

I remember something about the layout doesn't exist really inside the code and has to be inflated first, which is happening in the instantiateItem() function. And it's pretty obvious that it's going into the "view" variable. But when I call view.findViewById(R.id.light1_off);

which is a button by the way, it is always returning ZERO! I even made sure it only called when it was actually that page being loaded. But no matter what I did, it always keep returning a null and I get a nasty nullpointer exception.

Could someone help me out here? I'm pretty much out of ideas, and Google isn't of any help, already been to page 5 on about 10 different search terms.

like image 447
Henrik Avatar asked Nov 01 '11 15:11

Henrik


People also ask

Why is findViewById returning NULL?

FindViewById can be null if you call the wrong super constructor in a custom view. The ID tag is part of attrs, so if you ignore attrs, you delete the ID.

How to set ViewPager in Android?

Android ViewPager widget is found in the support library and it allows the user to swipe left or right to see an entirely new screen. Today we're implementing a ViewPager by using Views and PagerAdapter. Though we can implement the same using Fragments too, but we'll discuss that in a later tutorial.

What does findViewById return?

findViewById returns an instance of View , which is then cast to the target class. All good so far. To setup the view, findViewById constructs an AttributeSet from the parameters in the associated XML declaration which it passes to the constructor of View . We then cast the View instance to Button .


1 Answers

After much frustration and pulling my hair out over this issue, I have solved it! At least for me. Assuming you used the tutsplus tutorial like I did, you have separate XML files for your screens. Now, I assume those layout XMLs contain layouts within them (ie. LinearLayout, RelativeLayout, etc.). Now, those layouts contain your button and other widgets. What you have to do to be able to findViewById is, in the actual switch statement in the instatiateItem method, initialize your button in this way:

public Object instantiateItem(View collection, int position) {

    LayoutInflater inflater = (LayoutInflater) collection.getContext()
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    int resId = 0;
    switch (position) {
    case 0:
        resId = R.layout.lighttab;
        View view = inflater.inflate(resId, null);
        RelativeLayout layout=(RelativeLayout)view.findViewById(R.id.relLayout);
        Button button=(Button)layout.findViewById(R.id.button);
        ((ViewPager) collection).addView(view, 0);
        return view;
    case 1:
        resId = R.layout.securitytab;
        ...
        ...
        return view;
    }
}

So...first you have to inflate the view, then initialize the layout held within the view by casting the type of layout (RelativeLayout) and calling .findViewById(resource id). Then, you initialize the actual widget you're looking for by doing the same, but casting the widget type (Button) and calling .findViewById(resource id).

This worked for me, so I hope this saves you some trouble! Took forever for me to figure out.

like image 50
dennisdrew Avatar answered Nov 12 '22 09:11

dennisdrew