空指针exception – findViewById()
任何人都可以帮助我找出什么可以是这个程序的问题。 在onCreate()
方法中, findViewById()
对所有id都返回null,这会在稍后导致空指针exception。 我无法弄清楚为什么findViewById()
找不到视图。 有什么build议么?
这是主要的代码:
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_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>
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
。
您尝试获取的视图未在您的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; }
重点补充
对于Activity类中的那些情况。
Activity.findViewById(int id)
查找由
onCreate(Bundle)
处理的XML的id
属性标识的视图。
否则,如Fragment,Adapter, LayoutInflater
的View
等。
View.findViewById(int id)
使用给定的
id
查找子视图 。 如果这个视图有给定的id,则返回这个视图。
无论是哪种情况,
返回
视图如果find, 否则返回null
。
现在,重新检查你的XML文件。 确保将正确的值放入setContentView
或inflater.inflate
。
在Activity的情况下,在setContentView
之后调用findViewById
。
然后,确保在该布局中有一个您正在使用android:id="@+id/..."
查找的视图。 确保+
位于@+id
,这会将资源添加到R.id
值以确保您可以从Java中find它。
在访问它们之前将这些视图添加到寻呼机适配器。
@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访问它们。
今天我得到了这个错误,而且清楚这么简单,以至于我“面面俱到”。
只要尝试将UI元素添加到您的res / layout-port目录中的布局xml文件即可!
上面说的@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);
希望我的build议能帮助你
有时你需要在Eclipse中清理项目(Project – Clean ..)。
在Android中, findViewById(R.id.some_id)
在布局集合中查找视图时起作用。
也就是说,如果你已经设置了布局,就说:
setContentView(R.layout.my_layout);
视图只能在这个布局(my_layout)中find。
在你的代码中,布局1,布局2,布局3都是三种不同的布局,它们没有被设置为活动。
findViewById
方法必须find布局中的内容(您在setContentView
调用的内容)