使用Fragment开发登录页触发NullPointerException致App崩溃
空指针触发原因
- 核心原因:
R.id.RegisterUser按钮属于RegisterFragment布局内的控件,你在MainActivity中调用findViewById只能查找activity_main布局下的控件,无法检索到Fragment内部布局的控件,因此register变量被赋值为null,后续调用setOnClickListener时直接触发空指针。 - 代码隐患:
register成员变量声明为TextView类型,却被强转为Button类型,即使控件能被找到,也会抛出类型转换异常。 - 书写不规范问题:适配器中
addFragmet方法名拼写错误,正确拼写应为addFragment,该问题不会直接触发崩溃,但会降低代码可读性。
修复步骤
第一步:移除MainActivity中的无效逻辑
删除MainActivity里和register按钮相关的所有代码:- 删除成员变量声明
private TextView register; - 删除
onCreate方法中register = (Button) findViewById(R.id.RegisterUser);、register.setOnClickListener(this);两行代码 - 同步修正适配器的方法名拼写,将
addFragmet改为addFragment,两处调用该方法的位置同步修改。
修正后的MainActivity核心代码参考:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ViewPager viewPager = findViewById(R.id.viewPager); AuthenticationPagerAdapter pagerAdapter = new AuthenticationPagerAdapter(getSupportFragmentManager()); pagerAdapter.addFragment(new LoginFragment()); pagerAdapter.addFragment(new RegisterFragment()); viewPager.setAdapter(pagerAdapter); } class AuthenticationPagerAdapter extends FragmentPagerAdapter { private ArrayList<Fragment> fragmentList = new ArrayList<>(); public AuthenticationPagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int i) { return fragmentList.get(i); } @Override public int getCount() { return fragmentList.size(); } // 修正方法名拼写 void addFragment(Fragment fragment) { fragmentList.add(fragment); } } }- 删除成员变量声明
第二步:将注册按钮的逻辑迁移到RegisterFragment中
注意:Fragment的控件绑定必须在自身布局加载完成后操作,通过加载出的布局View对象查找控件,参考代码如下:public class RegisterFragment extends Fragment implements View.OnClickListener { private Button register; @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { // 加载Fragment自身的布局文件 View rootView = inflater.inflate(R.layout.fragment_register, container, false); // 基于Fragment的根布局查找控件 register = rootView.findViewById(R.id.RegisterUser); register.setOnClickListener(this); return rootView; } @Override public void onClick(View v) { if (v.getId() == R.id.RegisterUser) { // 启动注册页,使用宿主Activity的上下文 startActivity(new Intent(requireActivity(), RegisterUser.class)); } } }第三步:检查布局文件
确认activity_main.xml中仅放置ViewPager控件即可,原本属于登录、注册Fragment的按钮、输入框等控件,要分别放到fragment_login.xml、fragment_register.xml对应布局中,不要混写到Activity布局里。
内容的提问来源于stack exchange,提问作者SussyBaka
相关产品推荐
相关产品推荐

