动态创建MenuItem时使用SearchView出现空指针异常的解决方法
Hey, I totally get why you're hitting that NPE—let's break down what's going wrong and fix it step by step!
问题根源
你现在用findViewById(R.id.simpleSearchView)去查找SearchView,但这个SearchView是定义在单独的search_view.xml布局文件里的,并没有被加载到当前Activity的布局层级中,所以这个调用必然返回null,导致进入else分支。
正确的实现方式
有两种简单的方法可以解决这个问题,任选其一就行:
方法1:直接通过布局ID设置ActionView
你可以直接把布局ID传给setActionView(),系统会自动帮你inflate这个布局,之后再通过getActionView()获取SearchView实例:
@Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); MenuItem searchItem = menu.add(Menu.NONE, R.id.search_card, 1, R.string.search_card); searchItem.setIcon(R.drawable.search); searchItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); // 直接传入布局ID,系统自动加载 searchItem.setActionView(R.layout.search_view); // 获取已加载的SearchView实例 SearchView searchView = (SearchView) searchItem.getActionView(); if (searchView != null) { searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String s) { // 这里添加你的搜索提交逻辑 return true; } @Override public boolean onQueryTextChange(String s) { // 这里添加搜索文本变化的处理逻辑 return false; } }); } MenuItem trashCardItem = menu.add(Menu.NONE, R.id.delete_card, 2, R.string.delete_card); // 其他MenuItem的代码... return true; }
方法2:手动inflater加载布局
如果你需要对布局加载过程做更多自定义,可以手动用LayoutInflater加载布局:
@Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); MenuItem searchItem = menu.add(Menu.NONE, R.id.search_card, 1, R.string.search_card); searchItem.setIcon(R.drawable.search); searchItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); // 手动inflater加载search_view布局 LayoutInflater inflater = getLayoutInflater(); SearchView searchView = (SearchView) inflater.inflate(R.layout.search_view, null); searchItem.setActionView(searchView); if (searchView != null) { searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String s) { return true; } @Override public boolean onQueryTextChange(String s) { return false; } }); } MenuItem trashCardItem = menu.add(Menu.NONE, R.id.delete_card, 2, R.string.delete_card); // 其他MenuItem的代码... return true; }
额外注意事项
- 如果你使用的是AndroidX库,请确保导入的是
androidx.appcompat.widget.SearchView,而不是旧的android.widget.SearchView,避免出现类转换异常。 - 确认
search_view.xml中的android:id="@+id/simpleSearchView"和代码中引用的ID一致。
内容的提问来源于stack exchange,提问作者bob dylan
相关产品推荐
相关产品推荐

