2013-09-29 5 views
36

Может кто-нибудь помочь мне узнать, что может быть проблемой с этой программой. В методе onCreate()findViewById() возвращает значение null для всех идентификаторов, и это вызывает исключение нулевого указателя позже. Я не могу понять, почему findViewById() не может найти представление. Какие-либо предложения?Null pointer Exception - findViewById()

Это основной код:

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); 
     } 
    } 
} 

и связанные файлы XML:

activity_main расположение:

<?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 расположение:

<?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 л ayout:

<?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> 

И activity_third расположение:

<?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> 

ответ

63

findViewById() возвращает вид, если он существует в макете вы предусмотрели в setContentView(), в противном случае она возвращает нуль, и это то, что происходит с вами.

Пример, если вы setContentView(R.layout.activity_first);, а затем позвоните findViewById(R.id.first_View);, он вернет представление, которое является вашим макетом.

Но если вы звоните findViewById(R.id.second_View); он будет возвращать null так как не вид в вашем activity_first.xml макет называется @+id/second_View.

+0

Я включил все макеты в основной макет, и у меня больше нет исключения указателя на указатель. Спасибо за совет. – user2629828

+3

Когда я использовал это в другом представлении, отличном от отображаемого в настоящее время вида, тот появился. Чтобы преодолеть это нежелательное поведение, я назвал представление без использования setContentView следующим образом. layout1 = (LinearLayout) View.inflate (это, R.layout.first_View, null); Затем, чтобы получить доступ к чему-либо внутри, я мог бы использовать Button botton = (Button) layout1.findViewById (R.id.button1); Просто добавьте, чтобы было полезно кому-то. –

+0

Почему? В чем преимущество форсирования нас? –

2

Представления, которые вы пытаетесь получить, не определены в макете activity_main. Вам нужно программно раздувать мнения вы пытаетесь добавить к 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; 
} 
+0

Как получить доступ к представлениям в вашем mainactivity? – Denny

1

добавить эти мнения адаптер пейджера, прежде чем доступ к ним.

@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); 

} 

адаптер пейджера:

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. 

} 

здесь вы можете получить доступ к ним через findViewById.

0

Что сказано выше @Warlock правильно, вы должны парафировать LinearLayout Layout1, Layout2, layout3 прямым путем:

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); 

хотите мои рекомендации, которые помогут вам

0

В Android findViewById(R.id.some_id) работает, когда вы поиск вида в макете.

То есть, если вы установили макет сказать:

setContentView(R.layout.my_layout); 

Представления могут быть найдены только в этой схеме (my_layout).

В коде layout1, layout2, layout3 все три различные схемы, и они не установлены в деятельности.

0

Метод findViewById должен найти то, что находится в макете (который вы назвали в setContentView)

0

Иногда вам необходимо очистить свой проект в Eclipse (Project - Clean ..).

1

Я получил эту ошибку сегодня, и было так просто очистить, что я «facepalmed».

Просто попробуйте добавить элемент пользовательского интерфейса в свой макет xml. Файл в каталоге res/layout-port !!!

1

Выделено

Для тех случаев, в рамках класса Activity.

Activity.findViewById(int id)

находит вид, который был идентифицирован с помощью атрибута id из XML, который был обработан в onCreate(Bundle).


В противном случае, такие как фрагмент, адаптер, View от LayoutInflater и т.д.

View.findViewById(int id)

Посмотрите на представлен вид ребенка с данным id. Если это представление имеет данный идентификатор, верните это представление.


В любом случае,

Возвращает
мнение, если найден или null иначе.


Теперь повторно проверить файлы XML. Убедитесь, что вы поместили правильное значение в setContentView или inflater.inflate.

В случае совершения операции, звоните findViewById после setContentView.

Затем убедитесь, что в этом макете есть вид, который вы ищете с android:id="@+id/...". Удостоверьтесь, что + находится в @+id, что добавит ресурс в значения R.id, чтобы убедиться, что вы можете найти его на Java.