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

И макет 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>

Ответ 1

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

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

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

Ответ 2

Представления, которые вы пытаетесь получить, не определены в макете 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;
}

Ответ 3

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

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

Ответ 4

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

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

Ответ 5

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

Для тех случаев в классе 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.

Ответ 6

Что такое @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);

пожелайте, чтобы мои рекомендации вам помогли

Ответ 7

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

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

setContentView(R.layout.my_layout);

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

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

Ответ 8

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

Ответ 9

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

Ответ 10

В моем случае это была глупая ошибка с моей стороны. Я написал код в методе OnCreate, но он был выше строки кода setContentView. Когда я переместил код ниже этой строки, приложение начало работать нормально.

setContentView(R.layout.activity_main);