0

I am trying to swipe page horizontally but i am getting NullPointerException. I am trying to swipe 3 page and i am using textview and onclicklistener on that textview in one of those page.When i run application it continually showing exception.

Here is my logcat

01-08 19:07:21.400: E/AndroidRuntime(22391): FATAL EXCEPTION: main
01-08 19:07:21.400: E/AndroidRuntime(22391): java.lang.NullPointerException
01-08 19:07:21.400: E/AndroidRuntime(22391):    at com.programr.dishoom.HotelMap.showHotelMap(HotelMap.java:184)
01-08 19:07:21.400: E/AndroidRuntime(22391):    at com.programr.dishoom.HotelMap$MyPagerAdapter.instantiateItem(HotelMap.java:131)
01-08 19:07:21.400: E/AndroidRuntime(22391):    at android.support.v4.view.PagerAdapter.instantiateItem(PagerAdapter.java:110)
01-08 19:07:21.400: E/AndroidRuntime(22391):    at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:801)
01-08 19:07:21.400: E/AndroidRuntime(22391):    at android.support.v4.view.ViewPager.populate(ViewPager.java:930)
01-08 19:07:21.400: E/AndroidRuntime(22391):    at android.support.v4.view.ViewPager.populate(ViewPager.java:881)
01-08 19:07:21.400: E/AndroidRuntime(22391):    at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1366)
01-08 19:07:21.400: E/AndroidRuntime(22391):    at android.view.View.measure(View.java:12937)
01-08 19:07:21.400: E/AndroidRuntime(22391):    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5045)
01-08 19:07:21.400: E/AndroidRuntime(22391):    at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1369)
01-08 19:07:21.400: E/AndroidRuntime(22391):    at android.widget.LinearLayout.measureVertical(LinearLayout.java:660)
01-08 19:07:21.400: E/AndroidRuntime(22391):    at android.widget.LinearLayout.onMeasure(LinearLayout.java:553)
01-08 19:07:21.400: E/AndroidRuntime(22391):    at android.view.View.measure(View.java:12937)
01-08 19:07:21.400: E/AndroidRuntime(22391):    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5045)
01-08 19:07:21.400: E/AndroidRuntime(22391):    at android.widget.FrameLayout.onMeasure(FrameLayout.java:293)
01-08 19:07:21.400: E/AndroidRuntime(22391):    at android.view.View.measure(View.java:12937)
 01-08 19:07:21.400: E/AndroidRuntime(22391):   at android.widget.LinearLayout.measureVertical(LinearLayout.java:812)

Here is my full code.

 @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_hotel_map);
    menuList =  (ListView)findViewById(R.id.listView2);        
    }        
    MyPagerAdapter adapter = new MyPagerAdapter();
     myPager = (ViewPager) findViewById(R.id.myfivepanelpager);
     myPager.setAdapter(adapter);
     myPager.setCurrentItem(3);      
}

private class MyPagerAdapter extends PagerAdapter {

    public int getCount(){
        return 3;
    }

    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 = showHotelContact();             
            break;
        case 1:
            resId = showHotelAddress();         
            break;              
        case 2:     
            resId = showHotelMap();             
            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

    }

}

public int showHotelMap()
{
    int resId;
    resId = R.layout.clickformap;
TextView clickOnMap = (TextView)findViewById(R.id.clickmap);

clickOnMap.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View v) {
        Intent intent = new Intent (getApplicationContext(),ShowMap.class);
        startActivity(intent);

    }
});
    return resId;
}
public int showHotelAddress()
{
    int resId;
    resId = R.layout.hoteladdress;
    return resId;
}
public int showHotelContact()
{
    int resId;
    resId = R.layout.hotelcontact;
    return resId;
}

}

I don't understand why i am getting this error.
Please give me any hint or reference.

Charles
  • 50,943
  • 13
  • 104
  • 142
Sandip Armal Patil
  • 6,241
  • 21
  • 93
  • 160

3 Answers3

2

The context in which you're calling findViewById() is within the Activity. This checks the main layout that you set in setContent() via the onCreate() method of your Activity. If the TextView R.id.clickmap is not part of the view that you passed to the Activity, then it won't be found.

The Activity class itself is not aware of the views being created/destroyed in the PagerAdapter, so it can't find them. In order for findViewById() to work, you need to call it on the reference to the parent view that contains the class. It can be any parent in the View hierarchy, but it must be a parent or the view itself.

EDIT:

I don't know how you're calling showHotelMap(), but you need to use the parent view that contains the TextView that you're looking for:

View mainView = getMainView()
TextView clickOnMap = (TextView) mainView.findViewById(R.id.clickmap);
clickOnMap.setOnClickListener(......);

Where, getMainView() is some method in which you retrieve the reference to the view you need. How you do that is dependent on your implementation.

EDIT 2:

private class MyPagerAdapter extends PagerAdapter {

   ...

   public Object instantiateItem(View collection, int position) {

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

       View returnView = null;
       switch (position) {
          case 0: 
             returnView = showHotelContact(inflater);             
             break;
          ...   
       }

       return returnView;
   }

   ...


   public View showHotelMap(Inflater inflater)
   {
      View returnView = inflater.inflate(R.layout.clickformap, null);
      TextView clickOnMap = (TextView)returnView.findViewById(R.id.clickmap);

      clickOnMap.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
            Intent intent = new Intent (getApplicationContext(),ShowMap.class);
            startActivity(intent);
         }
      });
      return returnView;
   }
}

In this implementation, you're inflating the View within your method, setting it up, then returning it to the PagerAdapter. You don't need to add it to the ViewPager because the ViewPager itself will call instantiateItem() and add it to itself.

DeeV
  • 35,865
  • 9
  • 108
  • 95
  • Thanks for your answer... but what i need to add in getMainView()?. what reference i need to retrieve? – Sandip Armal Patil Jan 08 '13 at 14:15
  • Alright. Looking at your code, I think I've figured out what you're trying to do. Updating my answer. – DeeV Jan 08 '13 at 14:25
  • The Adapter is an innerClass of the Activity HotelMap, thats the reason he is calling findViewById in method showHotelMap, look at the stack trace of the logcat exception: com.programr.dishoom.HotelMap$MyPagerAdapter – noni Jan 08 '13 at 14:41
  • I know, but he's returning the layout ID of the layout he later inflates. I'm assuming that the ID is actually in that layout, so what he's actually doing is inflating the View that the `Textview` is in AFTER he tries to retrieve the widget inside. – DeeV Jan 08 '13 at 15:02
  • That is most likely related to something else entirely. Your ViewPager isn't receiving the touch events to determine if a swipe is occurring. – DeeV Jan 09 '13 at 12:21
1

You have a NullPointerException in:

TextView clickOnMap = (TextView)findViewById(R.id.clickmap);
clickOnMap.setOnClickListener(new View.OnClickListener()...

Probably R.id.clickmap is not the correct ID of your TextView and findViewById is returning null to clickOnMap, then you try to setOnClickListener to a null object.

Sam-In-TechValens
  • 2,501
  • 4
  • 34
  • 67
noni
  • 2,927
  • 19
  • 18
  • He would be getting a ClassCastException. The TextView doesn't exist in his main layout. – DeeV Jan 08 '13 at 14:00
  • ClassCastException is thrown when you try to make an explicit cast of an object type to another, ie: String a = "hola"; Calendar b = (Calendar) a; NullPointerException is when you get a non-referenced object. FindViewById returns NULL when you ask for a View with an ID that is not defined in the layout. – noni Jan 08 '13 at 14:43
  • It will throw a ClassCastException if it finds a View that's inside the View Hierarchy but you try to cast it as a class that it's not. I.E., if R.id.clickmap was a LinearLayout, the View would return, try to cast as a `TextView` then throw a `ClassCastException`. – DeeV Jan 08 '13 at 15:03
  • Yep, i didn't realized that there was an explicit cast on the code, i've copy pasted his code. The problem is that he is not posting his layouts, so we don't know if the IDs are OK. His problem is that he is mixing an inflate view with the views inside the Activity, I've read your code and it appears to be OK, the only thing that can continue throwing a nullpointer is that the view he is inflating has not a textview inside – noni Jan 08 '13 at 15:18
  • Right. I'm making a lot of assumptions on what he's trying to do, but from what it looks like all those methods at the bottom were supposed to be view inflaters that the Adapter uses. It *usually* doesn't make sense to have a main layout other than the ViewPager which doesn't actually have widgets itself so the Activity would never find anything. – DeeV Jan 08 '13 at 15:32
1

If you want to use findViewByID(), you need to reference it by its parent view.

You should be using something like this,

TextView clickOnMap = (TextView)ActivityName.this.findViewById(R.id.clickmap);
Sahil Mahajan Mj
  • 11,033
  • 8
  • 53
  • 100