it-roy-ru.com

Как добавить SearchWidget в панель действий?

Я пытаюсь добавить Search-ActionView в свое приложение (как описано здесь http://developer.Android.com/guide/topics/search/search-dialog.html#UsingSearchWidget ). К сожалению, я получаю исключение NullPointerException, и мне трудно определить, что на самом деле идет не так.

Я создал поисковую конфигурацию и поисковую активность, как показано на странице Android. Мой XML-файл меню выглядит так:

<menu xmlns:Android="http://schemas.Android.com/apk/res/Android" >
    ...
    <item
        Android:id="@+id/menu_item_search"
        Android:actionViewClass="Android.widget.SearchView"
        Android:icon="@drawable/icon_search"
        Android:showAsAction="always"
        Android:title="@string/action_bar_button_search">
    </item>

</menu>

Это метод, где выдается исключение:

public boolean onCreateOptionsMenu( Menu menu )
{
    MenuInflater menuInflater = getMenuInflater();
    menuInflater.inflate( R.menu.action_bar, menu );

    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    SearchView searchView = (SearchView) menu.findItem(R.id.menu_item_search).getActionView();

    // NullPointerException thrown here; searchView is null.
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
    searchView.setIconifiedByDefault(false);

    return super.onCreateOptionsMenu( menu );
}

Полная трассировка стека:

FATAL EXCEPTION: main
Java.lang.NullPointerException
at com.example.activities.Test.onCreateOptionsMenu(Test.Java:41)
at Android.app.Activity.onCreatePanelMenu(Activity.Java:2444)
at com.Android.internal.policy.impl.PhoneWindow.preparePanel(PhoneWindow.Java:408)
at com.Android.internal.policy.impl.PhoneWindow.invalidatePanelMenu(PhoneWindow.Java:759)
at com.Android.internal.policy.impl.PhoneWindow$1.run(PhoneWindow.Java:2997)
at Android.os.Handler.handleCallback(Handler.Java:605)
at Android.os.Handler.dispatchMessage(Handler.Java:92)
at Android.os.Looper.loop(Looper.Java:137)
at Android.app.ActivityThread.main(ActivityThread.Java:4507)
at Java.lang.reflect.Method.invokeNative(Native Method)
at Java.lang.reflect.Method.invoke(Method.Java:511)
at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:790)
at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:557)
at dalvik.system.NativeStart.main(Native Method)
26
Taig

используйте этот способ как в ссылка

public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.action_bar, menu);
        MenuItem searchItem = menu.findItem(R.id.menu_item_search);
        SearchView searchView = (SearchView) searchItem.getActionView();


        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        if(null!=searchManager ) {   
         searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
        }
        searchView.setIconifiedByDefault(false);

        return true;
    }
20
Dheeresh Singh

Поскольку этот вопрос рассматривается довольно часто, и я снова и снова сталкиваюсь с одной и той же проблемой, я приведу небольшое продолжение, которое отслеживает все необходимые шаги для создания SearchWidget.

Однако в SearchWidget есть одна сложная часть: Если вы используете жестко закодированные строки в searchable.xml вместо ресурсов, приложение вылетит с ошибочным сообщением об ошибке. Это заняло у меня слишком много часов моей жизни ...

  1. Создать действие для обработки результатов поиска

    public class Search extends Activity {}
    
  2. Добавьте файл «searchable.xml» в каталог res/xml ( используйте ресурсы для подсказок и меток! )

    <searchable xmlns:Android="http://schemas.Android.com/apk/res/Android"
        Android:hint="@string/search_hint"
        Android:includeInGlobalSearch="false"
        Android:label="@string/search_label"
        Android:searchSettingsDescription="@string/search_global_description" />
    
  3. Создайте соответствующий пункт меню "main.xml" в вашем каталоге res/menu

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:Android="http://schemas.Android.com/apk/res/Android" >
    
        <item
           Android:id="@+id/options_menu_main_search"
           Android:actionViewClass="Android.widget.SearchView"
           Android:icon="@drawable/icon_magnifier"
           Android:showAsAction="always"
           Android:title="Search"/>
    
    </menu>
    
  4. Обновите свой Manifest.xml: добавьте поисковое действие и укажите, какие действия могут получать цели поиска. Добавление <meta-data Android:name="Android.app.default_searchable" Android:value=".app.Search" /> к узлу activity делает его доступным для поиска. Добавление его в узел application делает все действия доступными для поиска.

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:Android="http://schemas.Android.com/apk/res/Android">
        <application>
            <meta-data
                Android:name="Android.app.default_searchable"
                Android:value=".app.Search" />
    
            <activity Android:name=".activities.Search" >
                <intent-filter>
                <action Android:name="Android.intent.action.SEARCH" />
            </intent-filter>
    
            <meta-data
                Android:name="Android.app.searchable"
                Android:resource="@xml/searchable" />
        </activity>
    </application>
    

  5. Добавляйте SearchManager в свой ActionView в каждом действии, которое должно предоставлять SearchWidget

    public class Activity extends Android.app.Activity
    {
        @Override
        public boolean onCreateOptionsMenu( Menu menu )
        {
            getMenuInflater().inflate( R.menu.main, menu );
    
            // Add SearchWidget.
            SearchManager searchManager = (SearchManager) getSystemService( Context.SEARCH_SERVICE );
            SearchView searchView = (SearchView) menu.findItem( R.id.options_menu_main_search ).getActionView();
    
            searchView.setSearchableInfo( searchManager.getSearchableInfo( getComponentName() ) );
    
            return super.onCreateOptionsMenu( menu );
        }
    }
    
49
Taig

Если вы используете таргетинг Android 2.x и используете Android.support.v7.widget.SearchView Убедитесь, что ваш menu.xml выглядит следующим образом (обратите внимание на yourapp namespace)

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:yourapp="http://schemas.Android.com/apk/res-auto">
    <item
        Android:id="@+id/search"
        Android:title="@string/search"
        Android:icon="@drawable/ic_search"
        yourapp:showAsAction="always"
        yourapp:actionViewClass="Android.support.v7.widget.SearchView" />
</menu>

А в Деятельности, где вы раздуваете меню, используйте:

Android.support.v7.widget.SearchView searchView = (Android.support.v7.widget.SearchView) 
MenuItemCompat.getActionView(menu.findItem(R.id.search));
24
peceps

SearchView getActionView возвращает ноль

Как и в ссылке, откройте свой XML-файл меню и измените 

Android:actionViewClass="Android.widget.SearchView"

в 

app:actionViewClass="Android.widget.SearchView" 

это сработало для меня

7
QuinnX

У меня тоже такая же проблема. В моем случае изменение Android:actionViewClass на app:actionViewClass решило проблему (С xmlns:app="http://schemas.Android.com/apk/res-auto" в теге <menu>).

2
stenlytw

Прежде всего, создайте файл XML, содержащий SearchWidget, в папку макета

<?xml version="1.0" encoding="utf-8"?>
<SearchView xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:id="@+id/edit_query"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:inputType="textFilter"
    >

</SearchView>

Затем, в вашей деятельности, получить панель действий

Android.support.v7.app.ActionBar actionBar = getSupportActionBar();

Затем добавьте ссылку на ваш вид поиска

 actionBar.setCustomView(R.layout.custom_action_bar);
    search = (EditText) actionBar.getCustomView().findViewById(
            R.id.edit_query);

Затем установите параметр отображения для панели действий

actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_HOME_AS_UP);

Вот и все. 

Кстати, вы также можете использовать мой поисковый виджет , который принимает список строк в виде списка массивов и отображает их в соответствии с введенным запросом. Как только пользователь выбирает конкретный результат, возвращается выбранный результат, который может быть извлечен в onActivityResult родительского действия. 

0
Riya Gayasen

Эта проблема вызвана отсутствующим фильтром намерений:

<intent-filter>
    <action Android:name="Android.intent.action.SEARCH" />
</intent-filter>
0
tpbapp