这段代码,在顶部注释了块,成功运行:
public class MainActivity extends AppCompatActivity {
/*
EditText username = (EditText)findViewById(R.id.editText_Username);
EditText password = (EditText)findViewById(R.id.editText_Password);
TextView inputdata = (TextView)findViewById(R.id.textView_InputData);
TextView welcome = (TextView)findViewById(R.id.textView_Welcome);
Button login=(Button)findViewById(R.id.button_Login);
Button anotherLogin=(Button)findViewById(R.id.button_Login_Another);
*/
public void doLoginOnClick(View v)
{
String s1=username.getText().toString();
inputdata.setText(s1);
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton)findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
}
我正在尝试使用捕获组件的id
findViewById(R.id.***)
正如你所看到的,我把这段代码放在代码开头的注释中。
EditText username = (EditText)findViewById(R.id.editText_Username);
EditText password = (EditText)findViewById(R.id.editText_Password);
TextView inputdata = (TextView)findViewById(R.id.textView_InputData);
TextView welcome = (TextView)findViewById(R.id.textView_Welcome);
Button login=(Button)findViewById(R.id.button_Login);
Button anotherLogin=(Button)findViewById(R.id.button_Login_Another);
如果我删除上面的评论并运行它(在模拟器和真实设备中),程序会立即崩溃,我很惊讶这里出了什么问题?
甚至我也尝试过用构造函数初始化同样的东西。
但如果我把它放在onCreate()
里面,就不会崩溃吗?为什么?
我试图获取用户名和密码的信息,并使用将其显示在textView_Inputdata
中的文本视图中
EditText username = (EditText)findViewById(R.id.editText_Username);
EditText password = (EditText)findViewById(R.id.editText_Password);
TextView inputdata = (TextView)findViewById(R.id.textView_InputData);
inputdata.setText(username.getText.toString()+" "+password.getText.toString());
有更好或更简单的方法吗?
实例成员变量在初始化实例本身时进行初始化。现在对findViewById()
来说还为时过早
在onCreate()
之前,您的活动还没有findViewById()
内部需要的Window
。在setContentView()
(您应该在onCreate()
中调用)之前,也找不到任何视图。
因此,在onCreate()
和setContentView()
之后初始化视图引用。
添加此代码
EditText username = findViewById(R.id.editText_Username);
EditText password = findViewById(R.id.editText_Password);
TextView inputdata = findViewById(R.id.textView_InputData);
TextView welcome = findViewById(R.id.textView_Welcome);
Button login = findViewById(R.id.button_Login);
Button anotherLogin = findViewById(R.id.button_Login_Another);
在中
onCreate();
后的方法
setContentView(R.layout.activity_main);
嘿,我看到您正在定义和初始化实例变量。我所做的是定义实例变量-EditText username
,然后在onCreate
方法中初始化它们-username = (EditText) findViewById(R.id.editText_Username);
不初始化实例变量的原因是,元素直到onCreate
方法中的setContentView
之后才准备好-我可能错了,但我的最佳实践是定义实例变量,然后在onCreate方法
在设置setContentView()之前,您无法初始化视图项。因为此时将不存在活动的视图。
将初始化保存在一个单独的方法中,并在将视图设置为活动后调用该方法。
您必须在onCreate()
中的setContentView()
之后调用findViewById()
,在此之前没有UI/Layout初始化,这就是为什么您的findViewById()
找不到ID并抛出NullPointerException
的原因。
public class MainActivity extends AppCompatActivity {
public void doLoginOnClick(View v){
String s1 = username . getText ().toString();
inputdata.setText(s1);
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar =(Toolbar) findViewById (R.id.toolbar);
setSupportActionBar(toolbar);
EditText username =(EditText) findViewById (R.id.editText_Username);
EditText password =(EditText) findViewById (R.id.editText_Password);
TextView inputdata =(TextView) findViewById (R.id.textView_InputData);
TextView welcome =(TextView) findViewById (R.id.textView_Welcome);
Button login =(Button) findViewById (R.id.button_Login);
Button anotherLogin =(Button) findViewById (R.id.button_Login_Another);
FloatingActionButton fab =(FloatingActionButton) findViewById (R.id.fab);
fab.setOnClickListener(new View . OnClickListener ()
{
@Override
public void onClick(View view)
{
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
}
在onCreate()方法之后初始化所有视图
点击此处阅读有关活动生命周期的更多信息
这样想吧——在告诉活动要使用哪个用户界面布局(xml)之前,它不知道从哪里获取这些视图
您可以执行setContentView(R.layout.your_xml)来告诉活动使用哪个布局作为活动的用户界面。您可以在onCreate回调中执行此操作,因为这是执行"一次性活动级别设置"任务的回调。setContentView()就是这样一个任务。完成此操作后,您可以开始访问布局文件R.layout.your_xml.中的视图
onCreate(...)
{
...
setContentView(R.layout.your_xml)
// Ready to use the views from above xml.
findViewById(R.id.your_view)
...
}
视图绑定将帮助您防止以下问题:
https://developer.android.com/topic/libraries/view-binding
或者在顶部声明视图,并在onCreate()中的setContentView()之后初始化它们。
public class MainActivity extends AppCompatActivity {
//Declare view on top
EditText username, password;
TextView inputdata,welcome;
Button login,notherLogin;
public void doLoginOnClick(View v)
{
String s1=username.getText().toString();
inputdata.setText(s1);
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//set view
username = findViewById(R.id.editText_Username);
password = findViewById(R.id.editText_Password);
inputdata = findViewById(R.id.textView_InputData);
welcome = findViewById(R.id.textView_Welcome);
login = findViewById(R.id.button_Login);
anotherLogin = findViewById(R.id.button_Login_Another);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton)findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
} }
setContentView()
负责膨胀活动的布局。如果在布局膨胀之前使用任何组件,则它将与NullPointerException
一起崩溃。
@Override
protected void onCreate(Bundle savedInstanceState)
{
setContentView(R.layout.activity_layout);
username = findViewById(R.id.editText_Username);
password = findViewById(R.id.editText_Password);
inputdata = findViewById(R.id.textView_InputData);
welcome = findViewById(R.id.textView_Welcome);
login = findViewById(R.id.button_Login);
anotherLogin = findViewById(R.id.button_Login_Another);
}
您仍然可以在类的开头声明变量,但必须在onCreate
中初始化它。