由于应用程序兼容,Searchview 不起作用
Posted
技术标签:
【中文标题】由于应用程序兼容,Searchview 不起作用【英文标题】:Searchview doesn't work since app compat 【发布时间】:2015-01-18 21:16:47 【问题描述】:自从我实现了应用兼容后,我的搜索视图不再起作用:
Process: com.laurenswuyts.witpa, PID: 26666
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.laurenswuyts.witpa.Activities.Events.EventActivity.onCreateOptionsMenu(EventActivity.java:75)
at android.app.Activity.onCreatePanelMenu(Activity.java:2820)
at android.support.v4.app.FragmentActivity.onCreatePanelMenu(FragmentActivity.java:275)
at android.support.v7.app.ActionBarActivity.superOnCreatePanelMenu(ActionBarActivity.java:276)
at android.support.v7.app.ActionBarActivityDelegate$1.onCreatePanelMenu(ActionBarActivityDelegate.java:79)
at android.support.v7.widget.WindowCallbackWrapper.onCreatePanelMenu(WindowCallbackWrapper.java:49)
at android.support.v7.internal.app.ToolbarActionBar.populateOptionsMenu(ToolbarActionBar.java:459)
at android.support.v7.internal.app.ToolbarActionBar$1.run(ToolbarActionBar.java:69)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
所以当我拥有它时,它是 searchview 的空指针:
@Override
public boolean onCreateOptionsMenu(Menu menu)
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.event_main, menu);
// Get the SearchView and set the searchable configuration
// Associate searchable configuration with the SearchView
SearchManager searchManager =
(SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView =
(SearchView) menu.findItem(R.id.action_search).getActionView();
searchView.setSearchableInfo(
searchManager.getSearchableInfo(getComponentName()));
return super.onCreateOptionsMenu(menu);
在我的菜单中我有这个:
<!-- Search Widget -->
<item android:id="@+id/action_search"
android:title="@string/action_search"
android:icon="@drawable/ic_action_search"
app:showAsAction="always"
android:actionViewClass="android.support.v7.widget.SearchView"/>
我不知道为什么它不再起作用了,但是自从我开始使用 app compat 21 后它就发生了。
问候,
【问题讨论】:
【参考方案1】:我与androidx.appcompat.widget.SearchView
有非常相似的问题,但原因不同。单击操作按钮时发生崩溃
Process: hotspotshield.android.***, PID: 26089
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.graphics.drawable.Drawable.getPadding(android.graphics.Rect)' on a null object reference
at androidx.appcompat.widget.SearchView.adjustDropDownSizeAndPosition(SearchView.java:1373)
at androidx.appcompat.widget.SearchView$4.onLayoutChange(SearchView.java:380)
at android.view.View.layout(View.java:20690)
at android.view.ViewGroup.layout(ViewGroup.java:6194)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1812)
原因是主题中缺少属性android:popupBackground
。实际上,材料 AppCompat 主题具有所需的背景,但尽管我的主题扩展自 Theme.AppCompat.Light
,但它仍然崩溃。
我找到的唯一解决方案是覆盖属性:
<style name="AppTheme" parent="Theme.AppCompat.Light">
<item name="android:popupBackground" tools:ignore="PrivateResource">@drawable/abc_popup_background_mtrl_mult</item>
</style>
它是 AppCompat 中使用的默认可绘制对象。它被标记为私有,但您可以使用它。或者自己声明背景可绘制
【讨论】:
【参考方案2】:如果启用 Proguard,则会出现问题。 可以通过将其添加到 proguard 规则来修复
-保持类 android.support.v7.widget.SearchView *;
【讨论】:
【参考方案3】:如果您像这样缩小构建类型,则需要在“proguard-rules.pro”文件中添加一行。
buildTypes
release
debuggable false
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
debug
debuggable true
minifyEnabled false
shrinkResources false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
在“proguard-rules.pro”文件中添加一行。
-keep class android.support.v7.widget.SearchView *;
【讨论】:
【参考方案4】:如果您使用 progurd 则必须将以下行添加到 proguard-rules.pro 文件中
-保持公共类 android.support.v7.widget.** *;
或
-保持类 android.support.v7.widget.SearchView *;
【讨论】:
【参考方案5】:在您点击结果后,您的应用预计操作尚未完成,并试图进一步进入 Intent 参数。
SearchView.OnSuggestionListener
并返回 true
通知您的应用点击操作已完成。
searchView.setOnSuggestionListener(new SearchView.OnSuggestionListener()
@Override
public boolean onSuggestionClick(int position)
return true;
@Override
public boolean onSuggestionSelect(int position)
return false;
);
【讨论】:
【参考方案6】:将以下行添加到位于 app 文件夹内的 proguard-rules.pro 文件中:
-保持类 android.support.v7.widget.SearchView *;
【讨论】:
【参考方案7】:这是 Simas 回答的附加信息。我在另一个答案 (https://***.com/a/33400808/4949671) 中发现了这一点,这对于解决我的异常非常重要:
请注意,
app:actionViewClass
不是android:actionViewClass
【讨论】:
【参考方案8】:玩了一段时间“运行和错误”后,我找到了解决方案。看起来 UI 元素不是导致错误的原因。将搜索设置为 QueryListener 后,它运行良好。这是一些代码:
Activity,其中包含 SearchBar:
@Override
public boolean onCreateOptionsMenu(Menu menu)
getMenuInflater().inflate(R.menu.menu_main, menu);
SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener()
@Override
public boolean onQueryTextSubmit(String s)
Log.d(TAG, "onQueryTextSubmit ");
return false;
@Override
public boolean onQueryTextChange(String s)
Log.d(TAG, "onQueryTextChange ");
return false;
);
return true;
searchable.xml
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_name"
android:hint="@string/search_hint"/>
以及menu.xml中的“SearchBar”
<item
android:id="@+id/search"
android:title="@string/search_title"
android:icon="@drawable/abc_ic_search_api_mtrl_alpha"
app:showAsAction="collapseActionView|ifRoom"
app:actionViewClass="android.support.v7.widget.SearchView"/>
...
最后但并非最不重要的是,清单(但这应该很清楚)......
<activity
android:name=".activities.MainActivity"
android:label="@string/title_activity_main">
<meta-data
android:name="android.app.searchable"
android:resource="@xml/searchable"/>
</activity>
更多信息 -> Docs
【讨论】:
【参考方案9】:如果您启用了 proguard 并且它正在剥离 SearchView
类,这也可能发生。您需要修改 proguard 设置以保留该类。
更多详情请参阅this问题。
【讨论】:
【参考方案10】:尝试为您的 actionViewClass
使用自定义 app
命名空间:
app:actionViewClass="android.support.v7.widget.SearchView"/>
【讨论】:
哇,好用,你能解释一下为什么我必须使用 app 而不是 android 吗? @Laurenswuyts 自从您开始使用支持库以来,现在必须使用自定义命名空间定义一些属性。您在菜单文件中定义了该命名空间。更多信息可以在the docs中找到。 我使用 app: 命名空间,它适用于调试版本,但是当我在 gradle.build 中设置 minifyEnabled true 时,它会在发布模式下导致相同的错误,有什么建议吗? @ Ashraf Alshahawy ...使用-keep class android.support.** *; 在 progaurd-rules 的情况下 minifyEnabled true以上是关于由于应用程序兼容,Searchview 不起作用的主要内容,如果未能解决你的问题,请参考以下文章
RecyclerView 的 SearchView 不起作用
为啥 recyclerview 的 searchview 不起作用?