两个类中都有findViewById()方法,Activity中的findViewById最终是调用View中的findViewById方法,这个可以从源码看出来:
public View findViewById(int id) {
return getWindow().findViewById(id);//activity中的方法
}
Activity是先拿到window对象,之后再拿view对象:
public View findViewById(int id) {
return getDecorView().findViewById(id); // window中的方法
}
最后才是调用View中的方法:
public final View findViewById(int id) {
if (id < 0) {
return null;
}
return findViewTraversal(id); //View中的方法
}
所以,如果在Activity中调用findViewById(int id)的时候,要注意id的来源,如果id不是在当前Activity所在的窗口,拿到的view对象就为空,比如:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View contentView = getLayoutInflater().inflate(R.layout.popup, null);
final PopupWindow popup = new PopupWindow(contentView, 280, 360);
Button button = (Button) findViewById(R.id.bn);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
popup.showAsDropDown(v);
}
});
Button button2 = (Button) findViewById(R.id.close);
button2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
popup.dismiss();
}
});
}
上面的R.id.close不是在activity_main.xml里面,而是在popup.xml里面(布局文件略),所以拿到的button2为null,要真想拿到button2对象,不能直接调用activity的findViewById()方法,而是调用view的findViewById()方法,改为这样就可以了:
Button button2 = (Button) contentView.findViewById(R.id.close);
button2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
popup.dismiss();
}
});