我似乎无法解决这个令人困惑的问题,我想在课堂上添加很多很多东西来帮助减少这种混乱。
由于多种方法都使用这些复选框变量。
我想将所有内容放在开头的正下方。
这是有效的,但不是我想要的。:
public class MyClass extends Activity implements View.OnClickListener {
//leaving out most code like onCreate. Just pretend it's there.
public void checkboth(View view) {
CheckBox cb1 = (CheckBox) findViewById(R.id.cb1);
CheckBox cb2 = (CheckBox) findViewById(R.id.cb2);
cb1.setchecked(true);
cb2.setchecked(true);
}
@Override
public void onClick(View v) {
}
}
但是对于我的生活,我无法弄清楚为什么我不能这样做:
public class MyClass extends Activity implements View.OnClickListener {
CheckBox cb1 = (CheckBox) findViewById(R.id.cb1);
CheckBox cb2 = (CheckBox) findViewById(R.id.cb2);
//leaving out most code like onCreate. Just pretend it's there.
public void checkboth(View view) {
cb1.setchecked(true);
cb2.setchecked(true);
}
@Override
public void onClick(View v) {
}
}
答案 0 :(得分:7)
您无法在类似
的方法之外初始化View
CheckBox cb1 = (CheckBox) findViewById(R.id.cb1);
CheckBox cb2 = (CheckBox) findViewById(R.id.cb2);
因为这意味着这些行在onCreate()
之前运行,这导致这些变量为null
,并在您尝试调用这些变量上的方法时抛出NPE
。这是因为您在setContentView(R.layout.your_layout)
内拨打onCreate()
,在Views
内拨打layout
“直播”。这意味着,只有通过调用layout
inflated
setContentView()
之后才能初始化它们。在尝试初始化setContentView()
之前,您必须致电Views
。没有办法绕过那一部分。
有些人可能会有所帮助的是创建一个单独的函数,在调用setContentView()
之后初始化这些变量。像这样的东西
public class MyActivity
// declare your Views so they are global to the class
TextView tv;
// more views
@Override
public void onCreat(stuff)
{
// super call
setContentView(R.layout.my_layout);
init();
然后在您的init()
函数中初始化您声明的所有Views
private void init()
{
tv = (TextView) findViewById(R.id.myTextView);
// more initializations
}
但您可以在onCreate()
,onResume()
或其他任何位置初始化它们,只要之后 setContentView()
以这种方式声明和初始化它们将确保它们对Activity
的其他函数,监听器,内部类等都可用。如果你有很多Views
,它可能会减少“混乱”。
答案 1 :(得分:2)
findViewById是一种可以在视图膨胀后从活动(或任何视图组)运行的方法。要将视图扩展为活动级别,通常调用setContentView。
由于尚未调用setContentView,因此没有视图附加到活动。
以下是如何操作
public class MyClass extends Activity implements View.OnClickListener {
CheckBox cb1;
CheckBox cb2;
public void onCreate(Bundle sis) {
super.onCreate(sis);
setContentView(R.layout.whatever);
cb1 = (CheckBox) findViewById(R.id.cb1);
cb2 = (CheckBox) findViewById(R.id.cb2);
}
public void checkboth(View view) {
cb1.setchecked(true);
cb2.setchecked(true);
}
@Override
public void onClick(View v) {
}
}
答案 2 :(得分:1)
您不能从此处调用方法(findViewById)并期望非空值。只有在调用setContentView(R.layout.my_layout)后才能在android中创建视图。你要做的是这样的事情:
public class MyClass extends Activity implements View.OnClickListener {
CheckBox cb1 = null;
CheckBox cb2 = null;
//leaving out most code like onCreate. Just pretend it's there.
public void onCreate(Bundle savedInstanceState)
{
super.onCreate();
setContentView(R.layout.my_layout);
cb1 = (CheckBox) findViewById(R.id.cb1);
cb2 = (CheckBox) findViewById(R.id.cb2);
}
public void checkboth(View view) {
cb1.setchecked(true);
cb2.setchecked(true);
}
@Override
public void onClick(View v) {
}
}
答案 3 :(得分:0)
将声明移动到类的顶部时,将局部变量更改为字段。创建实例时会初始化这些字段 - 这意味着它们在构造函数执行之前“正好”初始化。
现在,在对findViewById
的隐式调用完成之前,您无法调用实例方法(如super()
)。
将它们移动到构造函数中,事情应该成功。