我想将我的变量设置在我的类的顶部,而不是在方法中
我似乎无法解决这个令人困惑的问题,我有很多很多东西要在课堂上添加,以帮助减少混乱。
由于多种方法使用这些复选框变量。
我想把所有东西放在开口支架下面的顶部。
这是有效的,但不是我想要的:
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
)。
将它们移动到构造函数,事情应该成功。