如何将TextInputLayout输入存入SharedPreferences并在其他Activity展示?解决空指针异常
核心崩溃原因
报错NullPointerException: Attempt to invoke virtual method 'android.widget.EditText com.google.android.material.textfield.TextInputLayout.getEditText()' on a null object reference,本质是你调用findViewById获取的TextInputLayout对象为null,后续调用getEditText()自然触发空指针。
导致TextInputLayout为null的两个关键问题:
- RegistrationActivity的onCreate中未加载布局:你完全漏掉了
setContentView(R.layout.你的注册页面布局ID),没有加载布局时,所有findViewById都会返回null。 - ID匹配错误:你用的
R.id.TextInputEditText、R.id.PasswordInputEditText大概率是布局中内部EditText的ID,而非外层TextInputLayout的ID,用EditText的ID找TextInputLayout肯定找不到。
分步修复
1. 补全布局加载代码
在RegistrationActivity的onCreate开头,先调用setContentView加载你的注册页面布局,示例:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_registration); // 必须先加载布局 // 后续SharedPreferences、findViewById代码... }
2. 修正ID匹配
打开你的注册页面布局文件(比如activity_registration.xml),确认TextInputLayout的ID,示例布局结构:
<com.google.android.material.textfield.TextInputLayout android:id="@+id/til_name" <!-- 这是TextInputLayout的ID --> ...> <com.google.android.material.textfield.TextInputEditText android:id="@+id/TextInputEditText" <!-- 这是内部EditText的ID --> .../> </com.google.android.material.textfield.TextInputLayout>
然后在代码中用TextInputLayout的ID来findViewById:
// 替换成你布局中TextInputLayout的实际ID TextInputLayout nameField = findViewById(R.id.til_name); TextInputLayout passwordField = findViewById(R.id.til_password); TextInputLayout phoneField = findViewById(R.id.til_phone);
3. 增加空值安全判断(可选但推荐)
为了避免后续潜在的空指针,建议在调用getEditText()前先判断TextInputLayout是否为空:
if (nameField != null && nameField.getEditText() != null) { nameField.getEditText().setText(na); }
4. 优化:使用ViewBinding替代findViewById
ViewBinding能彻底避免ID匹配错误,还能简化代码,步骤如下:
- 在模块的build.gradle中启用ViewBinding:
android { ... buildFeatures { viewBinding true } }
- 修改RegistrationActivity的代码:
private ActivityRegistrationBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ActivityRegistrationBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); SharedPreferences file = getSharedPreferences("userData", MODE_PRIVATE); String na = file.getString("name", ""); String pas = file.getString("password2", ""); String ph = file.getString("phone", ""); // 直接通过binding访问TextInputLayout,无需findViewById if (binding.tilName.getEditText() != null) { binding.tilName.getEditText().setText(na); } if (binding.tilPassword.getEditText() != null) { binding.tilPassword.getEditText().setText(pas); } if (binding.tilPhone.getEditText() != null) { binding.tilPhone.getEditText().setText(ph); } } public void confirmInput(View v) { SharedPreferences file = getSharedPreferences("userData", MODE_PRIVATE); SharedPreferences.Editor editor = file.edit(); String name = ""; if (binding.tilName.getEditText() != null) { name = binding.tilName.getEditText().getText().toString(); } String password2 = ""; if (binding.tilPassword.getEditText() != null) { password2 = binding.tilPassword.getEditText().getText().toString(); } String phone = ""; if (binding.tilPhone.getEditText() != null) { phone = binding.tilPhone.getEditText().getText().toString(); } editor.putString("name", name); editor.putString("password2", password2); editor.putString("phone", phone); editor.apply(); // 推荐用apply()替代commit(),异步更高效 Intent in = new Intent(this, LoginActivity.class); startActivity(in); }
为什么之前用EditText正常?
因为你之前直接findViewById的是EditText的ID,且当时的Activity中正确调用了setContentView,所以能找到EditText对象;换成TextInputLayout后,既没加载布局,又用错了ID,才导致空指针崩溃。
内容的提问来源于stack exchange,提问作者Nutshoot12

