空指针异常 - 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 文件。确保将正确的值放入 setContentViewinflater.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) 中找到视图。

在您的代码中layout1layout2layout3 都是三种不同的布局,它们没有设置为活动。

【讨论】:

【参考方案11】:

findViewById 方法必须找到布局中的内容(您在 setContentView 中调用)

【讨论】:

【参考方案12】:

当您在 XML 文件中具有多个组件的相同名称时,也会产生此问题。即使它们是不同的布局文件,您也应该给每个元素一个唯一的名称。 发生此错误是因为您在另一个布局文件中有一个同名的 XML 元素,而 android studio 正在尝试访问该元素并显示此错误

【讨论】:

以上是关于空指针异常 - findViewById()的主要内容,如果未能解决你的问题,请参考以下文章

Android findViewById空指针[重复]

findViewById() 在与合并标签一起使用时在包含标签上抛出空指针

java中的空指针异常怎么解决

jsp 505空指针异常

Collectors.toMap空指针异常

SpringBoot配置拦截器空指针异常