Null pointer Exception – findViewById ()

Может ли кто-нибудь помочь мне узнать, что может быть проблемой с этой программой. В onCreate() findViewById() возвращает значение null для всех идентификаторов, и это вызывает исключение нулевого указателя позже. Я не могу понять, почему 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:

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

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

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

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

Представления, которые вы пытаетесь получить, не определены в макете activity_main . Вам необходимо программно раздувать просмотры, которые вы пытаетесь добавить в пейджер.

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

Добавлен акцент

Для этих случаев в классе 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/..." в этом макете. Убедитесь, что R.id + находится в @+id , который добавит ресурс в значения R.id чтобы убедиться, что вы можете найти его на Java.

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

 @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.

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

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

То, что сказал @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); 

Пожелайте, чтобы мой совет помог вам

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

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

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

 setContentView(R.layout.my_layout); 

Представления можно найти только в этом макете (my_layout).

В вашем layout1 , layout2 , layout3 все три разных макета, и они не настроены на активность.

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