无法在操作栏中使用SearchView

5
我尝试了很多教程、stackoverflow的解决方案和谷歌的教程,如https://www.youtube.com/watch?v=9OWmnYPX1uc,但我无法使搜索视图在我的操作栏中正常工作。请问有人知道我做错了什么吗?
我总是在searchView上得到一个nullpointerexception。
以下是我的Activity与listview:
@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

enter image description here 我想在一个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.access$100(AppCompatDelegateImplV7.java:89)
                                                                                      at android.support.v7.app.AppCompatDelegateImplV7$1.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)

解决方案

OMG 将android:actionViewClass="android.support.v7.widget.SearchView" 修改为 app:actionViewClass="android.support.v7.widget.SearchView"

然后,问题就迎刃而解了。


2
我建议使用工具栏而不是操作栏来完成这个任务。我可以帮你完成这个过程。 - Steve Kamau
编辑1:如果外观相同,那对我来说就可以了 ;) - vanlooverenkoen
好的,您可以点击上面的链接查看是否可行。我还建议使用更多的工具栏。这能给您更多自定义外观和功能的“自由”。我目前在我的列表视图和网格视图上使用了我已经简要介绍过的搜索功能。 - Steve Kamau
好的,我会尝试解决这个问题,完成后会通知您。 - vanlooverenkoen
我假设你也有一个适配器?请粘贴相关代码。 - Steve Kamau
显示剩余8条评论
3个回答

4
在您的 list_menu.xml 文件中,
android:actionViewClass="android.support.v7.widget.SearchView"

应该改为:

app:actionViewClass="android.support.v7.widget.SearchView"

0

由于您没有发布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

我忘记发布了,但我确实按照你写的做了。 - vanlooverenkoen

0
在你的工具栏布局中加入一个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>

在您的活动中,通过引用找到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"/>

这总是给我一个SearchView,我想要一个按钮,当我按下该按钮时,该字段会展开整个工具栏/操作栏。 - vanlooverenkoen
我有一个自定义适配器,无法使用getFilter()函数。 - vanlooverenkoen
现在,图标正在EditText上方浮动。 - vanlooverenkoen
我明白了。有一种方法可以做到这一点 https://dev59.com/JV4c5IYBdhLWcg3w7t_E - Steve Kamau
让我们在聊天中继续这个讨论 - vanlooverenkoen

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