java - 我的 Searchview 不起作用/给出 NullPointerException setSearchableInfo
问题描述
我花了我最后 8 个小时来解决这个简单的愚蠢 NPE(即将精神失明)。几乎阅读了有关此问题的所有内容,尝试了所有可能的但结果相同,所以我将发布所有相关的代码,我希望有人可以帮助 !
首先,这是我通过 logcat 得到的完整错误;
2019-03-12 11:16:56.130 23426-23426/com.demotxt.myapp.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.demotxt.myapp.myapplication, PID: 23426
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.SearchView.setSearchableInfo(android.app.SearchableInfo)' on a null object reference
at com.demotxt.myapp.myapplication.activities.Main3Activity.onCreateOptionsMenu(Main3Activity.java:130)
at android.app.Activity.onCreatePanelMenu(Activity.java:3317)
at android.support.v4.app.FragmentActivity.onCreatePanelMenu(FragmentActivity.java:340)
at android.support.v7.view.WindowCallbackWrapper.onCreatePanelMenu(WindowCallbackWrapper.java:93)
at android.support.v7.app.AppCompatDelegateImplBase$AppCompatWindowCallbackBase.onCreatePanelMenu(AppCompatDelegateImplBase.java:332)
at android.support.v7.view.WindowCallbackWrapper.onCreatePanelMenu(WindowCallbackWrapper.java:93)
at android.support.v7.app.ToolbarActionBar.populateOptionsMenu(ToolbarActionBar.java:454)
at android.support.v7.app.ToolbarActionBar$1.run(ToolbarActionBar.java:55)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
我的 Main3Activity 用于搜索;
public class Main3Activity extends AppCompatActivity {
private final String JSON_URL = "https://MYURLXX" ;
private JsonArrayRequest request ;
private RequestQueue requestQueue ;
private List<Anime> lstAnime ;
private RecyclerView recyclerView ;
RecyclerViewLiveAdapter adapter;
RecyclerView.LayoutManager layoutManager;
Toolbar toolbar;
SearchView searchView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
toolbar=findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
lstAnime = new ArrayList<>() ;
recyclerView = findViewById(R.id.recyclerviewid);
jsonrequest();
}
private void jsonrequest() {
request = new JsonArrayRequest(JSON_URL, new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
JSONObject jsonObject = null ;
for (int i = 0 ; i < response.length(); i++ ) {
try {
jsonObject = response.getJSONObject(i) ;
Anime anime = new Anime() ;
anime.setName(jsonObject.getString("name"));
anime.setDescription(jsonObject.getString("description"));
anime.setRating(jsonObject.getString("Rating"));
anime.setCategorie(jsonObject.getString("categorie"));
anime.setStudio(jsonObject.getString("studio"));
anime.setImage_url(jsonObject.getString("img"));
anime.setLink(jsonObject.getString("link"));
anime.setDrm_scheme(jsonObject.getString("drm_scheme"));
anime.setDrm_license_url(jsonObject.getString("drm_license_url"));
anime.setDrm(jsonObject.getString("drm"));
anime.setSubtitle(jsonObject.getString("subtitle"));
anime.setSubtitle1(jsonObject.getString("subtitle1"));
anime.setSubtitle2(jsonObject.getString("subtitle2"));
lstAnime.add(anime);
} catch (JSONException e) {
e.printStackTrace();
}
}
setuprecyclerview(lstAnime);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue = Volley.newRequestQueue(Main3Activity.this);
requestQueue.add(request) ;
}
private void setuprecyclerview(List<Anime> lstAnime) {
RecyclerViewLiveAdapter myadapter = new RecyclerViewLiveAdapter(this,lstAnime) ;
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(myadapter);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_item,menu);
MenuItem searchItem =menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) searchItem.getActionView();
SearchManager searchManager=(SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setIconifiedByDefault(false);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
newText=newText.toLowerCase();
List<Anime> myList=new ArrayList<>();
for (Anime anime:lstAnime){
String moviename =anime.getName().toLowerCase();
if (moviename.contains(newText))
myList.add(anime);
}
adapter.setSearchOperation(myList);
return false;
}
});
return true;
}
}
我的 RecyclerViewAdapter 中的相关部分;
public void setSearchOperation(List<Anime> newList) {
mData=new ArrayList<>();
mData.addAll(newList);
notifyDataSetChanged();
}
我在 res/xml 中的 searchable.xml;
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_name"
android:hint="@string/search" >
</searchable>
AndroidManifest.xml中Main3Activity的相关部分;
<activity android:name=".activities.Main3Activity">
<meta-data
android:name="android.app.searchable"
android:resource="@xml/searchable"
android:value=".activities.Main3Activity"/>
<intent-filter>
<action android:name="android.intent.action.SEARCH"/>
</intent-filter>
</activity>
这是工具栏在布局中的布局,由 RecyclerView 的布局调用,如“include layout ="@layout/toolbar_layout">
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark"></android.support.v7.widget.Toolbar>
这是菜单文件夹中的 menu_item xml 文件;
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<item
android:id="@+id/action_search"
android:icon="@drawable/ic_action_search"
android:title="Search Test"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="ifRoom|collapseActionView"/>
</menu>
我不使用 pro-guard 所以不是这样,我总是使用 app:showAsAction 和 app:actionViewClass 但正如我所说的那样,我在同一行得到了 nullpointerexception,提前谢谢!
解决方案
用此行替换您对 SearchView 的初始化
SearchView searchView = new SearchView(this.getSupportActionBar().getThemedContext());
推荐阅读
- asp.net-core - 适用于 Microsoft.NETCore.App 3.0.0 的 Nuget 不可用?
- java - 使用 Java 更新 excel
- python - 如何在 Python 中自定义排序两个 pandas 数据框列?
- unity3d - 你能在 Unity 中根据 .png 文件的像素网格进行寻路吗?
- security - 无法在 wso2 中使用 Secure Vault
- c# - 问题传递
- 对象到多维数组
- markdown - 防止标题成为从降价创建的投影仪中的新幻灯片
- .net - 触发器——指定的事件类型在指定的目标对象上是/无效的
- reactjs - 条件满足时在循环内循环应返回 newsingleArray
- android - 如何在 Facebook、Instagram、Messenger 等后台更新应用程序?