【问题标题】:Null pointer Exception - findViewById()空指针异常 - 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_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 布局:

<?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 布局:

 <?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_第三个布局:

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

【问题讨论】:

    标签: android nullpointerexception oncreate findviewbyid


    【解决方案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 正在尝试访问该元素并显示此错误

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 2023-02-15
                      • 2015-07-12
                      相关资源
                      最近更新 更多