空指针异常 - findViewById()
Posted
技术标签:
【中文标题】空指针异常 - findViewById()【英文标题】:Null pointer Exception - findViewById() 【发布时间】:2013-10-05 09:15:59 【问题描述】:谁能帮我找出这个程序的问题所在。
在onCreate()
方法中,findViewById()
为所有 id 返回 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_
android:layout_
android:background="#a4c639">
<android.support.v4.view.ViewPager
android:layout_
android:layout_
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_
android:layout_
android:id="@+id/first_View">
<TextView
android:layout_
android:layout_
android:text="@string/hello_world" />
<Button
android:id="@+id/button1"
style="?android:attr/buttonStyleSmall"
android:layout_
android:layout_
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_
android:layout_
android:id="@+id/second_View">
<TextView
android:layout_
android:layout_
android:text="@string/hello_world" />
</LinearLayout>
还有activity_第三个布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:id="@+id/third_View">
<TextView
android:layout_
android:layout_
android:text="@string/hello_world" />
</LinearLayout>
【问题讨论】:
【参考方案1】:findViewById()
如果视图存在于您在setContentView()
中提供的布局中,则返回一个视图,否则返回 null,这就是发生在您身上的事情。请注意,如果您没有setContentView()
,并且没有对findViewById()
的有效视图,findViewById()
将始终返回 null,直到您调用 setContentView()
。
这也意味着***变量会触发 NPE,因为它们在 onCreate()
之前被调用,并且通过扩展,在 setContentView()
之前被调用。另见the activity lifecycle
例如,如果您 setContentView(R.layout.activity_first);
然后调用 findViewById(R.id.first_View);
它将返回一个视图,这是您的布局。
但是如果你在setContentView()
之前调用findViewById(R.id.second_View);
,它将返回null
,因为在你的activity_first.xml
布局中没有一个名为@+id/second_View
的视图。
【讨论】:
我已将所有布局包含在主布局中,并且不再有空指针异常。感谢您的提示。 当我在当前显示视图之外的不同视图上使用它时,出现了那个。为了克服这种不需要的行为,我在不使用 setContentView 的情况下引用了该视图,如下所示。 layout1 = (LinearLayout) View.inflate(this, R.layout.first_View, null);然后要访问其中的任何内容,我可以使用 Button botton = (Button) layout1.findViewById(R.id.button1);只是添加它可能对某人有所帮助。 为什么?强迫我们有什么好处? 那么解决办法是把setContentView()
中没有提供的资源包含进来。【参考方案2】:
强调
对于 Activity 类中的那些情况。
Activity.findViewById(int id)
从
onCreate(Bundle)
中处理的 XML 中查找由id
属性标识的视图。
否则,如 Fragment、Adapter、View
来自 LayoutInflater
等。
View.findViewById(int id)
查找具有给定
id
的子视图。如果此视图具有给定的 id,则返回此视图。
无论哪种情况,
退货 如果找到视图或
null
否则。
现在,重新检查您的 XML 文件。确保将正确的值放入 setContentView
或 inflater.inflate
。
如果是 Activity,请在 setContentView
之后调用 findViewById
。
然后,确保在该布局中存在您正在寻找的带有android:id="@+id/..."
的视图。确保+
位于@+id
,这会将资源添加到R.id
值中,以确保您可以从Java 中找到它。
【讨论】:
【参考方案3】:您尝试获取的视图未在您的 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;
【讨论】:
如何访问 mainactivity 中的视图?【参考方案4】:有时您需要在 Eclipse 中清理您的项目(Project - Clean..)。
【讨论】:
为我解决了这个问题 - 这是一个手动步骤,而且错误会损害 id 查找,这很荒谬。 .我认为机器总是合乎逻辑的——到底有什么能以这种方式破坏代码?!【参考方案5】:在访问它们之前将这些视图添加到寻呼机适配器。
@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 访问它们。
【讨论】:
【参考方案6】:就我而言,这是一个愚蠢的错误。我在 OnCreate 方法中编写了代码,但它高于 setContentView
代码行。一旦我将代码移到这一行下方,应用程序就开始正常工作了。
setContentView(R.layout.activity_main);
【讨论】:
【参考方案7】:使用适配器扩展布局,并根据位置搜索视图。
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)
【讨论】:
【参考方案8】:上面@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);
希望我的建议对你有所帮助
【讨论】:
【参考方案9】:我今天收到了这个错误,很容易清除,以至于我“捂脸”。
只需尝试将 UI 元素添加到 res/layout-port 目录中的布局 xml 文件中!!!
【讨论】:
【参考方案10】:在 Android 中,findViewById(R.id.some_id)
在您在布局集中查找视图时起作用。
也就是说,如果你设置了一个布局说:
setContentView(R.layout.my_layout);
只能在此布局 (my_layout) 中找到视图。
在您的代码中layout1
、layout2
、layout3
都是三种不同的布局,它们没有设置为活动。
【讨论】:
【参考方案11】:findViewById
方法必须找到布局中的内容(您在 setContentView
中调用)
【讨论】:
【参考方案12】:当您在 XML 文件中具有多个组件的相同名称时,也会产生此问题。即使它们是不同的布局文件,您也应该给每个元素一个唯一的名称。 发生此错误是因为您在另一个布局文件中有一个同名的 XML 元素,而 android studio 正在尝试访问该元素并显示此错误
【讨论】:
以上是关于空指针异常 - findViewById()的主要内容,如果未能解决你的问题,请参考以下文章