搜索小部件,空指针?

3

您好,我在应用程序中实现搜索小部件时遇到了问题。似乎无法找到菜单项的“actionview”,但是它能够很好地找到该项。

我已经寻找答案,但没有看到明确的解决方案。

以下是我在XML中声明的菜单:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/group_search_box"
    android:title="@string/search_label"
    android:icon="@drawable/ic_action_action_search"
    app:showAsAction="ifRoom|collapseActionView"
    app:actionViewClass="android.support.v7.widget.SearchView" />

以下是它的实现方式。

SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE);
    MenuItem searchMenuItem = menu.findItem(R.id.group_search_box);
    SearchView searchView = (SearchView) searchMenuItem.getActionView();
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName()));

这里是我正在添加的库,也许我添加了一个不正确的库?

compile 'com.android.support:support-v4:+'
compile 'com.android.support:appcompat-v7:+'

最后,这是崩溃日志。

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.SearchView.setSearchableInfo(android.app.SearchableInfo)' on a null object reference
        at com.example.myapp.fragments.GroupFragment.onCreateOptionsMenu(GroupFragment.java:88)
        at android.app.Fragment.performCreateOptionsMenu(Fragment.java:1780)
        at android.app.FragmentManagerImpl.dispatchCreateOptionsMenu(FragmentManager.java:1927)
        at android.app.Activity.onCreatePanelMenu(Activity.java:2539)
        at android.support.v4.app.FragmentActivity.onCreatePanelMenu(FragmentActivity.java:224)
        at com.android.internal.policy.impl.PhoneWindow.preparePanel(PhoneWindow.java:436)
        at com.android.internal.policy.impl.PhoneWindow.doInvalidatePanelMenu(PhoneWindow.java:800)
        at com.android.internal.policy.impl.PhoneWindow$1.run(PhoneWindow.java:221)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
        at android.view.Choreographer.doCallbacks(Choreographer.java:574)
        at android.view.Choreographer.doFrame(Choreographer.java:543)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
        at android.os.Handler.handleCallback(Handler.java:733)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:5017)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)

我完全按照文档的要求操作,但仍然无法解决问题。

你解决了吗?不知为何,这种崩溃对我来说很罕见。 - android developer
我也遇到了这个异常。它的发生完全是随机的,这使得诊断问题变得困难。 - Milo
4个回答

6

今天我也遇到了同样的问题,但通过以下方法解决了混乱:

我也使用了以下依赖项,

compile 'com.android.support:support-v4:+'
compile 'com.android.support:appcompat-v7:+'

这意味着我将活动类从Activity类扩展为AppCompatActivity。因此,在这段代码中,
SearchView searchView =
                (SearchView) menu.findItem(R.id.action_search).getActionView();
        searchView.setSearchableInfo(
                searchManager.getSearchableInfo(getComponentName()));

这里应该使用的是 android.support.v7.widget.SearchView,而不是 android.widget.SearchView。这就是你出现问题的原因。请注意修改。
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.SearchView.setSearchableInfo(android.app.SearchableInfo)' on a null object reference

并且,还有以下内容:
<item
        android:id="@+id/action_search"
        app:actionViewClass="android.support.v7.widget.SearchView"
        android:icon="@android:drawable/ic_search_category_default"
        android:title="Search"
        app:showAsAction="always|collapseActionView" />

请注意, 它是app:actionViewClass而不是android:actionViewClass

@StarWind,你哪部分不工作,我不明白你的问题。 - diyoda_
啊,看起来是这个应用程序兼容性的问题。我试图使用“android:Theme.Material”,但它不能与AppCompatActivity一起使用。这很遗憾,因为我真的需要两者。但是,由于我已经花了几个小时在这上面了... - StarWind0
如果您在这方面遇到困难,请将其作为新问题添加到@StarWind中。 - diyoda_
我已经搞定了。对于我的未来同行,请参考https://dev59.com/N2Ei5IYBdhLWcg3wJZZe,如何在没有应用兼容库的情况下实现此功能。 - StarWind0

0

检查res文件夹中的菜单文件夹。 在我的情况下,会创建两个文件 第一个是原始文件,第二个是自动创建的21文件。 如果出现重复问题,请删除另一个文件以解决问题。


0

我曾经遇到过同样的问题,答案中提供的解决方案都对我不起作用。但是代码的这个更改对我有用。

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:appcompat="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/group_search_box"
android:title="@string/search_label"
android:icon="@drawable/ic_action_action_search"
appcompat:showAsAction="ifRoom|collapseActionView"
appcompat:actionViewClass="android.support.v7.widget.SearchView" />

请注意更改,"app:actionViewClass" 已更改为 "appcompat:actionViewClass"。
对我来说效果很好,希望对你也有用。

1
你的理由是不正确的。将 app 更改为 appCompat 没有任何作用。 这样做有效的原因是因为 app:actionViewClass="android.support.v7.widget.SearchView"。我之前使用了 android:actionViewClass,所以它对我没有起作用。 - Ali Kazi
@AliKazi 我没有给出任何理由,只是分享了对我有效的解决方案。虽然我应该提供一个理由。这一切都与您使用的SDK版本有关。对于我的版本(Sdk版本25),从“android:”到“app:”的更改不起作用,但是从“android:”到“appcompat:”的更改非常有效。对于您使用的版本,从“android”到“app”的更改有效。即使我也无法理解兼容性的多样性。 - captain.am
@captain.am,你的解决方案最初没有起作用,因为你在这里没有引用正确的命名空间属性 xmlns:appcompat="http://schemas.android.com/apk/res-auto",无论你将其命名为 appcompat 还是 appIncompat 都是无关紧要的。 - Chisko

-1

您应该从searchManager中删除getActivity(),如下所示,

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
     MenuItem searchItem = menu.findItem(R.id.searchMenuItem);
     SearchManager searchManager =
            (SearchManager) getSystemService(Context.SEARCH_SERVICE);

     android.support.v7.widget.SearchView searchView =
            (android.support.v7.widget.SearchView) MenuItemCompat.getActionView(searchItem);

     searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
     searchView.setIconifiedByDefault(false);

}

嘿,谢谢你的帮助,似乎没有起作用。目前这个代码是在一个片段内部,因为我只想在片段在屏幕上时才能使用该搜索功能。因此需要使用getActivities。作为一个测试,我把所有的代码都提取到了主Activity中,但是我仍然遇到了完全相同的问题,我可以找到菜单项,但是当我尝试获取actionView时会出现nullpointer。 - Spittal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接