【问题标题】:Adding SearchView in Fragment在 Fragment 中添加 SearchView
【发布时间】:2016-03-21 09:00:18
【问题描述】:

试图在操作栏中包含一个搜索视图。为此,我做了以下工作:

在菜单文件夹中创建了 MenuSearch.xml,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
   <item
    android:id="@+id/action_search"
    android:actionViewClass="Android.Support.V7.Widget.SearchView"
    android:icon="@android:drawable/ic_menu_search"
    android:showAsAction="always"
    android:title="Search"/>

</menu>

在片段中包含方法 OnCreateOptionsMenu:

public override void OnCreateOptionsMenu(IMenu menu, MenuInflater inflater)
    {
        inflater.Inflate(Resource.Menu.MenuSearch, menu);
        base.OnCreateOptionsMenu(menu, inflater);
        var searchManager = (SearchManager) this.Activity.GetSystemService(Context.SearchService);
        searchView = (SearchView) (menu.FindItem(Resource.Id.action_search).ActionView);
        searchView.SetSearchableInfo(searchManager.GetSearchableInfo(Activity.ComponentName));

    }

我已经在片段的 oncreate 中设置了HasOptionsMenu = true;

使用上面的代码,我在 searchView.SetSearchableInfo... 行中得到空指针。不知道为什么会发生这种情况,尽管一切似乎都正确且到位。

根据解决类似问题的一些建议,我还尝试了以下搜索视图选项。

        var item = menu.FindItem (Resource.Id.action_search);
        var searchItem = MenuItemCompat.GetActionView(item);
        searchView = searchItem.JavaCast<Android.Support.V7.Widget.SearchView>();
        searchView.SetSearchableInfo(searchManager.GetSearchableInfo(Activity.ComponentName));

但同样,我将 searchView 设为 null。

现在我已经尝试了可能的选项,我不知道为什么 searchview 变为空。

非常感谢任何帮助。

【问题讨论】:

    标签: android xamarin searchview


    【解决方案1】:

    将您的 MenuSearch.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">
            <item android:id="@+id/action_search"
                android:title="@string/app_name"
                android:icon="@drawable/ic_action_search"
                app:showAsAction="collapseActionView|ifRoom"
                 />
        </menu>
    

    在你的片段中,添加searchView.setOnQueryTextListener

        @Override
            public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
                super.onCreateOptionsMenu(menu, inflater);
                menu.clear();
                inflater.inflate(R.menu.search_option_menu, menu);
                MenuItem item = menu.findItem(R.id.action_search);
                SearchView searchView = new SearchView(((MainActivity) mContext).getSupportActionBar().getThemedContext());
               // MenuItemCompat.setShowAsAction(item, //MenuItemCompat.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW | //MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
               //  MenuItemCompat.setActionView(item, searchView);
               // These lines are deprecated in API 26 use instead
     item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW | MenuItem.SHOW_AS_ACTION_IF_ROOM);
            item.setActionView(searchView);
                searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
                    @Override
                    public boolean onQueryTextSubmit(String query) {
                        return false;
                    }
                    @Override
                    public boolean onQueryTextChange(String newText) {
                        return false;
                    }
                });
                searchView.setOnClickListener(new View.OnClickListener() {
                                                  @Override
                                                  public void onClick(View v) {
    
                                                  }
                                              }
                );
            }
    

    【讨论】:

    • 在 SearchView 上获取 nullPointerException searchView = new SearchView(((MainActivity) mContext).getSupportActionBar().getThemedContext());
    • 您的应用程序样式可能不支持操作栏。请检查您的风格是否如此。
    • MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW | MenuItemCompat.SHOW_AS_ACTION_IF_ROOM); MenuItemCompat.setActionView(item, searchView); 这两行已弃用,请更新答案......
    • 解决了我的问题。谢谢。
    【解决方案2】:

    答案已于 2018 年更新。如果您使用的是 Java,对不起 Kotlin。

    您的 xml 菜单资源(例如 search_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">
        <item android:id="@+id/action_search"
            android:title="@string/app_name"
            android:icon="@drawable/ic_search"
            app:showAsAction="collapseActionView|ifRoom"
            />
    </menu>
    

    构建代码:

    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater?) {
        super.onCreateOptionsMenu(menu, inflater)
        menu.clear()
        inflater?.inflate(R.menu.search_menu, menu)
        val searchView = SearchView((context as MainActivity).supportActionBar?.themedContext ?: context)
        menu.findItem(R.id.action_search).apply {
            setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW or MenuItem.SHOW_AS_ACTION_IF_ROOM)
            actionView = searchView
        }
    
        searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
            override fun onQueryTextSubmit(query: String): Boolean {
                return false
            }
    
            override fun onQueryTextChange(newText: String): Boolean {
                return false
            }
        })
        searchView.setOnClickListener {view ->  }
    }
    

    您可能还需要将此行放入onCreate()(为我的片段工作)以使这一切出现:

    setHasOptionsMenu(true)
    

    【讨论】:

      【解决方案3】:

      对于 2018 年末和 API >= 26 兼容(弃用警告)和格式正确的答案:

      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">
          <item android:id="@+id/action_search"
              android:title="Search_change_me_with_proper_id"
              android:icon="@drawable/ic_action_search"
              app:showAsAction="collapseActionView|ifRoom"/>
      </menu>
      

      ActivityFragment里面的Java代码:

      @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container,
                               Bundle savedInstanceState) {
          setHasOptionsMenu(true); // Add this!
          return inflater.inflate(R.layout.fragment_add_app, container, false);
      }
      
      @Override
      public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
          super.onCreateOptionsMenu(menu, inflater);
          menu.clear();
      
          inflater.inflate(R.menu.menu_add_app, menu);
          MenuItem item = menu.findItem(R.id.action_search_menu_add_app);
          item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW | MenuItem.SHOW_AS_ACTION_IF_ROOM);
      
          SearchView searchView = (SearchView) item.getActionView();
          searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
      
              @Override
              public boolean onQueryTextSubmit(String query) {
                  return false;
              }
      
              @Override
              public boolean onQueryTextChange(String newText) {
                  // Here is where we are going to implement the filter logic
                  return true;
              }
      
          });
      }
      

      或者作为第二个选项,您让ActivityFragment 实现SearchView.OnQueryTextListener,然后使用菜单搜索:

      @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container,
                               Bundle savedInstanceState) {
          setHasOptionsMenu(true); // Add this! (as above)
          return inflater.inflate(R.layout.fragment_add_app, container, false);
      }
      
      @Override
      public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
          super.onCreateOptionsMenu(menu, inflater);
          menu.clear();
          inflater.inflate(R.menu.menu_add_app, menu);
          MenuItem item = menu.findItem(R.id.action_search_menu_add_app);
          item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW | MenuItem.SHOW_AS_ACTION_IF_ROOM);
      
          SearchView searchView = (SearchView) item.getActionView();
          searchView.setOnQueryTextListener(this); // Fragment implements SearchView.OnQueryTextListener
      }
      
      @Override
      public boolean onQueryTextChange(String query) {
          // Here is where we are going to implement the filter logic
          return false;
      }
      
      @Override
      public boolean onQueryTextSubmit(String query) {
          return false;
      }
      

      【讨论】:

        【解决方案4】:

        我解决了这个问题我想分享我对 searchView NullPointerException 的答案

        我们需要从 Main Activity 中删除下面的方法

              public boolean onOptionsItemSelected(MenuItem item) {
                  int id = item.getItemId();  
                  return true;
        

        并在 OnActivityCreated setHasOptionsMenu(true) 中使用内部片段 和覆盖方法

            @Override
            public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
                 inflater.inflate(R.menu.menu, menu);
            }
        
            @Override
             public boolean onOptionsItemSelected(MenuItem item) {
               // handle item selection
                switch (item.getItemId()) {
                    case R.id.action_search:
        
             //       onCall();   //your logic
        
                    return true;
                default:
                    return super.onOptionsItemSelected(item);
            }
        }
        

        【讨论】:

          【解决方案5】:

          您的 search_options_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">
              <item android:id="@+id/action_search"
                  android:title="@string/app_name"
                  android:icon="@drawable/ic_action_search"
                  app:showAsAction="collapseActionView|ifRoom"
                   />
          </menu>
          

          在片段的 onCreate() 中覆盖片段 setHasOptionsMenu(true); 中的 onCreateOptionMenu 方法。

          @Override
              public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
                  super.onCreateOptionsMenu(menu, inflater);
                 menu.clear();
                  inflater.inflate(R.menu.search_option_menu, menu);
                  MenuItem item = menu.findItem(R.id.action_search);
                          SearchView searchView = (SearchView) MenuItemCompat.getActionView(menuItem);
                  MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW | MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
                  MenuItemCompat.setActionView(item, searchView);
                  searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
                      @Override
                      public boolean onQueryTextSubmit(String query) {
                          return false;
                      }
                      @Override
                      public boolean onQueryTextChange(String newText) {
                              //Do search code here
                          return true;
                      }
                  });
          
              }
          

          【讨论】:

            【解决方案6】:
            search_view.setOnQueryTextListener(object: SearchView.OnQueryTextListener {
                        override fun onQueryTextSubmit(query: String?): Boolean {
                            return false
                        }
            
                        override fun onQueryTextChange(query: String?): Boolean {
                            adapter.filter.filter(query)
                            return true
                        }
                    })
            

            并且不要在清单文件中为您的活动添加意图过滤器。

            【讨论】:

              【解决方案7】:

              在我的片段的 onCreateOptionsMenu 代码

              SearchManager searchManager =
                      (SearchManager)getActivity().getSystemService(Context.SEARCH_SERVICE);
              SearchableInfo searchableInfo =
                      searchManager.getSearchableInfo(getActivity().getComponentName());
              searchItem = menu.findItem(R.id.menu_search);
              SearchView searchView = (SearchView) searchItem.getActionView();
              searchView.setSearchableInfo( searchableInfo);
              

              产生以下错误信息: java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“void android.support.v7.widget.SearchView.setSearchableInfo (android.app.SearchableInfo)”

              在我将 menu.xml android:actionViewClass 更改为 app:actionViewClass 后,问题不再发生。 菜单.xml:

              <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="...">
              <item
              android:id="@+id/menu_search"
              android:title="@string/menu_search"
              app:actionViewClass="android.support.v7.widget.SearchView"
              app:showAsAction="ifRoom">
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2016-02-22
                • 1970-01-01
                • 1970-01-01
                • 2016-09-10
                • 2021-06-18
                • 2017-01-12
                相关资源
                最近更新 更多