我想将我的变量设置在我的类的顶部,而不是在方法中

我似乎无法解决这个令人困惑的问题,我有很多很多东西要在课堂上添加,以帮助减少混乱。

由于多种方法使用这些复选框变量。

我想把所有东西放在开口支架下面的顶部。

这是有效的,但不是我想要的:

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) { } } 

您无法在此类方法之外初始化View

 CheckBox cb1 = (CheckBox) findViewById(R.id.cb1); CheckBox cb2 = (CheckBox) findViewById(R.id.cb2); 

因为这意味着这些行在onCreate()之前运行,导致这些变量为null并在尝试调用这些变量上的方法时抛出NPE 。 这是因为你在onCreate()调用了setContentView(R.layout.your_layout) ,并且在那个layout调用了你的Views “live”。 这意味着在调用setContentView() layout inflated之前,无法初始化它们。 在尝试初始化Views之前,必须调用setContentView() 。 没有办法绕过那一部分。

有些人可能会有所帮助的是创建一个单独的函数,在调用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它可能会减少“混乱”。

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) { } } 

你不能从这里调用方法(findViewById)并期望一个非null值。 只有在调用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) { } } 

将声明移动到类的顶部时,将局部变量更改为字段。 创建实例时会初始化这些字段 – 这意味着它们会在构造函数执行之前“初始化”。

现在,在对super()的隐式调用完成之前,您无法调用实例方法(如findViewById )。

将它们移动到构造函数,事情应该成功。