无法使操作栏中的 SearchView 正常工作
Can't get SearchView in actionbar to work
我尝试了很多教程、Whosebug 解决方案和 google 教程 -> https://www.youtube.com/watch?v=9OWmnYPX1uc,但我无法在操作栏中使用搜索视图。
有没有人看出我做错了什么?
我总是在 searchView 上得到空指针异常
我的 Activity 列表视图:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.list_menu, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
searchView.setOnQueryTextListener(
new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
Toast.makeText(ContactListActivity.this, query, Toast.LENGTH_SHORT).show();
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
Toast.makeText(ContactListActivity.this, newText, Toast.LENGTH_SHORT).show();
return false;
}
}
);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
ComponentName componentName = new ComponentName(getApplicationContext(), TorrentListActivity.class);
searchView.setSearchableInfo(searchManager.getSearchableInfo(componentName));
return true;
}
Searchable.xml
<?xml version="1.0" encoding="utf-8"?>
<searchable
android:label="@string/app_name"
xmlns:android="http://schemas.android.com/apk/res/android"
android:hint="Search"
android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"/>
list_menu.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"
tools:context="be.vanlooverenkoen.torrentsearch.TorrentListActivity">
<item
android:id="@+id/action_search"
android:title="Search"
android:icon="@drawable/ic_action_search"
app:showAsAction="ifRoom|collapseActionView"
android:actionViewClass="android.support.v7.widget.SearchView"/>
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:title="@string/menu_settings"
app:showAsAction="never" />
</menu>
编辑 1
我不想要 1 Activity 上的建议,但在另一个 activity 上我需要过滤我的 listview
的列表
**编辑 2 **
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.LinkedList;
import be.vanlooverenkoen.torrentsearch.CommonUtilities.CommonUtilities;
import be.vanlooverenkoen.torrentsearch.model.Torrent;
/**
* Created by Koen on 19/03/2016.
*/
public class TorrentListAdapter extends BaseAdapter {
private LinkedList<Torrent> torrents;
private LayoutInflater layoutInflater;
public TorrentListAdapter(Context context, LinkedList<Torrent> torrents) {
this.torrents = torrents;
layoutInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return torrents.size();
}
@Override
public Object getItem(int position) {
return torrents.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.list_row_layout, null);
holder = new ViewHolder();
holder.titleView = (TextView) convertView.findViewById(R.id.txt_title);
holder.seedView = (TextView) convertView.findViewById(R.id.txt_seedsValue);
holder.peerView = (TextView) convertView.findViewById(R.id.txt_peersValue);
holder.sizeView = (TextView) convertView.findViewById(R.id.txt_sizeValue);
holder.dateView = (TextView) convertView.findViewById(R.id.txt_datevalue);
holder.torrentTypeTitleView = (TextView) convertView.findViewById(R.id.torrenttypetitle);
holder.torrentTypeView = (TextView) convertView.findViewById(R.id.torrentTypeView);
holder.verifiedImg = (ImageView) convertView.findViewById(R.id.verified);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Torrent torrent = torrents.get(position);
holder.titleView.setText(torrent.getTitle());
Log.d("Seeds", String.valueOf(holder.titleView.getText()));
holder.seedView.setText(String.valueOf(torrent.getSeeds()));
holder.peerView.setText(String.valueOf(torrent.getPeers()));
holder.sizeView.setText(torrent.getSize());
holder.dateView.setText(torrent.getDateOfRelease());
if(CommonUtilities.checkForShowTorrentType(layoutInflater.getContext())){
holder.torrentTypeView.setText(torrent.getTorrentType());
holder.torrentTypeTitleView.setText("Torrent Type:");
}else{
holder.torrentTypeView.setText("");
holder.torrentTypeTitleView.setText("");
}
if (torrent.isLegitUploader()) {
holder.verifiedImg.setImageResource(R.drawable.verified);
}else{
holder.verifiedImg.setImageDrawable(null);
}
return convertView;
}
static class ViewHolder {
TextView titleView;
TextView seedView;
TextView peerView;
TextView sizeView;
TextView dateView;
TextView torrentTypeTitleView;
TextView torrentTypeView;
ImageView verifiedImg;
}
}
编辑 3
FATAL EXCEPTION: main
Process: be.vanlooverenkoen.torrentsearch, PID: 10509
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.SearchView.setOnQueryTextListener(android.support.v7.widget.SearchView$OnQueryTextListener)' on a null object reference
at be.vanlooverenkoen.torrentsearch.TorrentListActivity.onCreateOptionsMenu(TorrentListActivity.java:105)
at android.app.Activity.onCreatePanelMenu(Activity.java:2852)
at android.support.v4.app.FragmentActivity.onCreatePanelMenu(FragmentActivity.java:298)
at android.support.v7.view.WindowCallbackWrapper.onCreatePanelMenu(WindowCallbackWrapper.java:85)
at android.support.v7.app.AppCompatDelegateImplBase$AppCompatWindowCallbackBase.onCreatePanelMenu(AppCompatDelegateImplBase.java:241)
at android.support.v7.app.AppCompatDelegateImplV7.preparePanel(AppCompatDelegateImplV7.java:1273)
at android.support.v7.app.AppCompatDelegateImplV7.doInvalidatePanelMenu(AppCompatDelegateImplV7.java:1553)
at android.support.v7.app.AppCompatDelegateImplV7.access0(AppCompatDelegateImplV7.java:89)
at android.support.v7.app.AppCompatDelegateImplV7.run(AppCompatDelegateImplV7.java:129)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5422)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
解决方案
我的天啊
android:actionViewClass="android.support.v7.widget.SearchView"
一定是
app:actionViewClass="android.support.v7.widget.SearchView"
然后它起作用了
因为您没有 post AndroidManifest.xml
文件,我猜您没有更改它。您应该添加:
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data android:name="android.app.searchable"
android:resource="@xml/searchable" />
到 <activity android:name=".TorrentListActivity" ... >
标记,让您的应用知道它可以在其中搜索。
我使用的教程:http://developer.android.com/training/search/setup.html
在您的 Toolbar
布局中添加一个 EditText
:
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:minHeight="?attr/actionBarSize"
android:background="#2196F3"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/inputSearch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="@drawable/edit_text_transparent"
android:hint="Search..."
android:imeOptions="actionDone"
android:singleLine="true"
android:textColorHint="#fff" />
</android.support.v7.widget.Toolbar>
edit_text_transparent.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:padding="10dp"
android:shape="rectangle">
<solid android:color="@android:color/transparent" />
<stroke
android:width="0dp"
android:color="@android:color/transparent" />
<corners
android:bottomLeftRadius="5dp"
android:bottomRightRadius="5dp"
android:topLeftRadius="5dp"
android:topRightRadius="5dp" />
</shape>
在您的 activity 中通过引用找到 EditText
小部件并添加 TextWatcher
来过滤结果:
inputSearch = (EditText) findViewById(R.id.inputSearch);
inputSearch.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// When user changed the Text
if (cs.length() > 0) {
adapter.getFilter().filter(cs);
} else {
//no search results were returned
TextView search = (TextView) findViewById(R.id.no_results);
search.setVisibility(View.INVISIBLE);
adapter.getFilter().filter(cs);
}
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
@Override
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
}
});
编辑
您是否在 menu.xml 中的搜索项中添加了此命名空间:
app:actionViewClass="android.support.v7.widget.SearchView"/>
并且也在清单中:
<meta-data
android:name="android.app.searchable"
android:resource="@xml/searchable"/>
在你的list_menu.xml,
android:actionViewClass="android.support.v7.widget.SearchView"
应改为:
app:actionViewClass="android.support.v7.widget.SearchView"
我尝试了很多教程、Whosebug 解决方案和 google 教程 -> https://www.youtube.com/watch?v=9OWmnYPX1uc,但我无法在操作栏中使用搜索视图。
有没有人看出我做错了什么?
我总是在 searchView 上得到空指针异常
我的 Activity 列表视图:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.list_menu, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
searchView.setOnQueryTextListener(
new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
Toast.makeText(ContactListActivity.this, query, Toast.LENGTH_SHORT).show();
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
Toast.makeText(ContactListActivity.this, newText, Toast.LENGTH_SHORT).show();
return false;
}
}
);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
ComponentName componentName = new ComponentName(getApplicationContext(), TorrentListActivity.class);
searchView.setSearchableInfo(searchManager.getSearchableInfo(componentName));
return true;
}
Searchable.xml
<?xml version="1.0" encoding="utf-8"?>
<searchable
android:label="@string/app_name"
xmlns:android="http://schemas.android.com/apk/res/android"
android:hint="Search"
android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"/>
list_menu.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"
tools:context="be.vanlooverenkoen.torrentsearch.TorrentListActivity">
<item
android:id="@+id/action_search"
android:title="Search"
android:icon="@drawable/ic_action_search"
app:showAsAction="ifRoom|collapseActionView"
android:actionViewClass="android.support.v7.widget.SearchView"/>
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:title="@string/menu_settings"
app:showAsAction="never" />
</menu>
编辑 1
**编辑 2 **
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.LinkedList;
import be.vanlooverenkoen.torrentsearch.CommonUtilities.CommonUtilities;
import be.vanlooverenkoen.torrentsearch.model.Torrent;
/**
* Created by Koen on 19/03/2016.
*/
public class TorrentListAdapter extends BaseAdapter {
private LinkedList<Torrent> torrents;
private LayoutInflater layoutInflater;
public TorrentListAdapter(Context context, LinkedList<Torrent> torrents) {
this.torrents = torrents;
layoutInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return torrents.size();
}
@Override
public Object getItem(int position) {
return torrents.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.list_row_layout, null);
holder = new ViewHolder();
holder.titleView = (TextView) convertView.findViewById(R.id.txt_title);
holder.seedView = (TextView) convertView.findViewById(R.id.txt_seedsValue);
holder.peerView = (TextView) convertView.findViewById(R.id.txt_peersValue);
holder.sizeView = (TextView) convertView.findViewById(R.id.txt_sizeValue);
holder.dateView = (TextView) convertView.findViewById(R.id.txt_datevalue);
holder.torrentTypeTitleView = (TextView) convertView.findViewById(R.id.torrenttypetitle);
holder.torrentTypeView = (TextView) convertView.findViewById(R.id.torrentTypeView);
holder.verifiedImg = (ImageView) convertView.findViewById(R.id.verified);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Torrent torrent = torrents.get(position);
holder.titleView.setText(torrent.getTitle());
Log.d("Seeds", String.valueOf(holder.titleView.getText()));
holder.seedView.setText(String.valueOf(torrent.getSeeds()));
holder.peerView.setText(String.valueOf(torrent.getPeers()));
holder.sizeView.setText(torrent.getSize());
holder.dateView.setText(torrent.getDateOfRelease());
if(CommonUtilities.checkForShowTorrentType(layoutInflater.getContext())){
holder.torrentTypeView.setText(torrent.getTorrentType());
holder.torrentTypeTitleView.setText("Torrent Type:");
}else{
holder.torrentTypeView.setText("");
holder.torrentTypeTitleView.setText("");
}
if (torrent.isLegitUploader()) {
holder.verifiedImg.setImageResource(R.drawable.verified);
}else{
holder.verifiedImg.setImageDrawable(null);
}
return convertView;
}
static class ViewHolder {
TextView titleView;
TextView seedView;
TextView peerView;
TextView sizeView;
TextView dateView;
TextView torrentTypeTitleView;
TextView torrentTypeView;
ImageView verifiedImg;
}
}
编辑 3
FATAL EXCEPTION: main
Process: be.vanlooverenkoen.torrentsearch, PID: 10509
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.SearchView.setOnQueryTextListener(android.support.v7.widget.SearchView$OnQueryTextListener)' on a null object reference
at be.vanlooverenkoen.torrentsearch.TorrentListActivity.onCreateOptionsMenu(TorrentListActivity.java:105)
at android.app.Activity.onCreatePanelMenu(Activity.java:2852)
at android.support.v4.app.FragmentActivity.onCreatePanelMenu(FragmentActivity.java:298)
at android.support.v7.view.WindowCallbackWrapper.onCreatePanelMenu(WindowCallbackWrapper.java:85)
at android.support.v7.app.AppCompatDelegateImplBase$AppCompatWindowCallbackBase.onCreatePanelMenu(AppCompatDelegateImplBase.java:241)
at android.support.v7.app.AppCompatDelegateImplV7.preparePanel(AppCompatDelegateImplV7.java:1273)
at android.support.v7.app.AppCompatDelegateImplV7.doInvalidatePanelMenu(AppCompatDelegateImplV7.java:1553)
at android.support.v7.app.AppCompatDelegateImplV7.access0(AppCompatDelegateImplV7.java:89)
at android.support.v7.app.AppCompatDelegateImplV7.run(AppCompatDelegateImplV7.java:129)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5422)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
解决方案
我的天啊 android:actionViewClass="android.support.v7.widget.SearchView" 一定是 app:actionViewClass="android.support.v7.widget.SearchView"
然后它起作用了
因为您没有 post AndroidManifest.xml
文件,我猜您没有更改它。您应该添加:
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data android:name="android.app.searchable"
android:resource="@xml/searchable" />
到 <activity android:name=".TorrentListActivity" ... >
标记,让您的应用知道它可以在其中搜索。
我使用的教程:http://developer.android.com/training/search/setup.html
在您的 Toolbar
布局中添加一个 EditText
:
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:minHeight="?attr/actionBarSize"
android:background="#2196F3"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/inputSearch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="@drawable/edit_text_transparent"
android:hint="Search..."
android:imeOptions="actionDone"
android:singleLine="true"
android:textColorHint="#fff" />
</android.support.v7.widget.Toolbar>
edit_text_transparent.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:padding="10dp"
android:shape="rectangle">
<solid android:color="@android:color/transparent" />
<stroke
android:width="0dp"
android:color="@android:color/transparent" />
<corners
android:bottomLeftRadius="5dp"
android:bottomRightRadius="5dp"
android:topLeftRadius="5dp"
android:topRightRadius="5dp" />
</shape>
在您的 activity 中通过引用找到 EditText
小部件并添加 TextWatcher
来过滤结果:
inputSearch = (EditText) findViewById(R.id.inputSearch);
inputSearch.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// When user changed the Text
if (cs.length() > 0) {
adapter.getFilter().filter(cs);
} else {
//no search results were returned
TextView search = (TextView) findViewById(R.id.no_results);
search.setVisibility(View.INVISIBLE);
adapter.getFilter().filter(cs);
}
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
@Override
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
}
});
编辑
您是否在 menu.xml 中的搜索项中添加了此命名空间:
app:actionViewClass="android.support.v7.widget.SearchView"/>
并且也在清单中:
<meta-data
android:name="android.app.searchable"
android:resource="@xml/searchable"/>
在你的list_menu.xml,
android:actionViewClass="android.support.v7.widget.SearchView"
应改为:
app:actionViewClass="android.support.v7.widget.SearchView"