Исключение нулевого указателя - 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 пытается получить к нему доступ и показывает эту ошибку.