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