Исключение нулевого указателя - findViewById()

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

расположение деятельности_основной:

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

деятельность_первый макет:

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

активность_второй макет:

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

И макет активность_третье:

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

12 ответов

Решение

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

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

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

Акцент добавлен

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

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

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

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

setContentView(R.layout.activity_main);

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

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

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

      override fun instantiateItem(collection: ViewGroup, position: Int) : ViewGroup {
    val inflater = LayoutInflater.from(mContext)
    val layout = inflater.inflate(mData[position], collection, false) as ViewGroup

    if(position == your_position) {
       val nameOfField: TextView = layout.findViewById(R.id.item_id)
    }

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

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

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

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

setContentView(R.layout.my_layout);

Виды можно найти только в этом макете (my_layout).

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

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

То, что @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);

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

Эта проблема также возникает, когда у вас есть одно и то же имя для многих компонентов в XML-файле. Даже если это разные файлы макета, вы должны дать каждому элементу уникальное имя. Эта ошибка возникает из-за того, что у вас есть элемент XML с тем же именем в другом файле макета, и студия Android пытается получить к нему доступ и показывает эту ошибку.

Другие вопросы по тегам