У меня возникли проблемы с тем, чтобы интерфейс Android Search работал в панели действий

Я пробовал следовать руководству здесь, но у меня возникают некоторые проблемы. Я правильно получил значок поиска, который появится в панели действий, но у меня возникли проблемы с привязкой searchable configuration к SearchView.

Мой файл res/menu/options_menu.xml:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/search"
          android:title="@string/search_title"
          android:icon="@drawable/search"
          android:showAsAction="collapseActionView|ifRoom"
          android:actionViewClass="android.widget.SearchView" />
</menu>

Мой файл res/xml/searchable.xml(Примечание: мне пришлось создать папку "xml" в папке res, потому что ее не было. Я не думаю, что это должно иметь значение, хотя?

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
        android:label="@string/app_name"
        android:hint="@string/search_hint" />

Мои res/values ​​/strings.xml файл:

<?xml version="1.0" encoding="utf-8"?>
<resources>

<string name="app_name">Starting To Feel It</string>
<string name="single_post">Single Post View</string>
<string name="search">Search Activity</string>

<string name="action_settings">Settings</string>
<string name = "pagination_last">Last</string>
<string name = "pagination_next">Next</string>

<string name = "player_play">Play</string>
<string name = "player_previous">Previous</string>
<string name = "player_next">Next</string>
<string name = "player_playlist">Playlist</string>
<string name = "player_progress_bar">Progress Bar</string>

<string name="drawer_open">Open navigation drawer</string>
<string name="drawer_close">Close navigation drawer</string>


<string name="search_title">Search STFI</string>
<string name="search_hint">Search STFI</string>


<string name="menu_item_picture">Menu Item Picture</string>

</resources>

Мой файл AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.stfi"
android:versionCode="1"
android:versionName="1.0" >

<uses-permission android:name="android.permission.INTERNET"></uses-permission>

<uses-sdk
    android:minSdkVersion="14"
    android:targetSdkVersion="17" />

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:largeHeap="true"
    android:theme="@android:style/Theme.Holo.Light" >


    <activity
        android:name=".StartingToFeelIt"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>


    <activity
        android:name=".activities.SinglePost"
        android:label="@string/single_post">

    </activity>

    <activity 
        android:name=".activities.SearchActivity" 
        android:label="@string/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>

</manifest>

Все мои действия расширяют класс, который я назвал MenuActivity, и вот функция onCreateOptionsMenu define в MenuActivity.java:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.options_menu, menu);

    // Associate searchable configuration with the SearchView
    SearchManager searchManager =
            (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    SearchView searchView =
            (SearchView) menu.findItem(R.id.search).getActionView();

    System.out.println("The component name is " + this.getComponentName().toString());

    SearchableInfo info = searchManager.getSearchableInfo(getComponentName());

    if(info  == null)
    {
        System.out.println("It is null!");
    }

    searchView.setSearchableInfo(info);

    return true;
}

Я всегда получаю эту информацию в этой функции null. Я не уверен, что я делаю неправильно, чтобы получить информацию, является нулевой, и я не уверен, как ее исправить. Я не уверен, нужен вам это или нет, но ниже мой класс SearchActivity. Сейчас он ничего не делает, кроме как попытаться отобразить поиск (однако он никогда не вызывается, потому что конфигурация поиска настроена неправильно). Файл сохраняется в com.stfi.activities.SearchActivity.java.

Другое примечание. Когда я распечатываю имя компонента в приведенной выше функции, я получаю The component name is ComponentInfo(com.stfi/com.stfi.StartingToFeelIt), а не только com.stfi.StartingToFeelIt. Это заставляет меня думать, что что-то не так с моим файлом AndroidManifest, но я понятия не имею, является ли это причиной того, почему я не могу прикрепить конфигурацию поиска.

public class SearchActivity extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
    handleIntent(getIntent());
}

@Override
protected void onNewIntent(Intent intent) {
    handleIntent(intent);
}

private void handleIntent(Intent intent) {

    if (Intent.ACTION_SEARCH.equals(intent.getAction()))
    {
        String query = intent.getStringExtra(SearchManager.QUERY);
        System.out.println("You are searchin " + query);
    }
}
}

Ответы

Ответ 1

Я уже много думал и нашел две вещи, которые вам нужно сделать.

1. Обновите свой Manifest.xml и используйте <meta, чтобы добавить свой интерфейс поиска.

2.. Чтобы иметь возможность поиска, вам нужно добавить метаданные

<activity ... >
    ...
    <meta-data android:name="android.app.searchable"
            android:resource="@xml/searchable" />

</activity>

Ответ 2

Вероятно, проблема с манифестом, я думаю,

<meta-data
        android:name="android.app.default_searchable"
        android:value=".SearchActivity" />

отсутствует в вашем теге активности манифеста для "StartToFeelIt"

 <activity
    android:name=".StartingToFeelIt"
    android:label="@string/title_activity_main" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>

    <meta-data
        android:name="android.app.default_searchable"
        android:value=".SearchActivity" />
</activity>

также вы можете использовать ABS CollapsibleSearchMenu Lib.

Ответ 3

     <activity
        android:name="com.yourapp.YourSearchActivity"
        android:label="@string/title_activity_search"
        android:launchMode="singleTop" >
        <intent-filter>
            <action android:name="android.intent.action.SEARCH" />
        </intent-filter>

        <meta-data
            android:name="android.app.searchable"
            android:resource="@xml/searchable" />
    </activity>

В моем меню 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="com.example.mirrorcamera.MainActivity" >

    <item
        android:id="@+id/search"
        android:showAsAction="always"
        android:title="@string/string_title"/>

</menu>

Код Java:

public class SearchActivity extends ListActivity {

    private static final int             ICON = R.drawable.ic_ab_back_holo_light;
    private SearchDataBaseAdapter        searchDataBaseAdapter;
    private ArrayList<SearchResultModel> searchResultList;
    private ResultListAdapter            resultListAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_search);

        super.onCreate(savedInstanceState);

        searchResultList = new ArrayList<SearchResultModel>();

        // gets the db reference from adapter
        searchDataBaseAdapter = new SearchDataBaseAdapter(this);
        searchDataBaseAdapter.open();

        handleIntent(getIntent());

    }



    /**
     * Handles the intent from the search.
     * 
     * @param intent
     */
    private void handleIntent(Intent intent) {
        if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
            // handles a search query
            String query = intent.getStringExtra(SearchManager.QUERY);
            search(query);

        }
    }



    @Override
    public void onNewIntent(Intent intent) {
        // super.onNewIntent(intent);
        setIntent(intent);
        handleIntent(intent);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {

        case R.id.search:
            onSearchRequested();
            break;
        }

        return true;
    }

    /**
     * Search function.
     * 
     * @param searchTerm
     */
    public void search(String searchTerm) {

        try {
            Cursor cursor = searchDataBaseAdapter.getWordMatches(searchTerm, null);
            //create and add your list to your adapter.
            resultListAdapter = new ResultListAdapter(this, itemsFound(cursor, cursor.getString(cursor.getColumnIndex("YOUR_COLUMN"))));
        } catch (NullPointerException ex) {
            Toast.makeText(this, "Search Term not found", Toast.LENGTH_LONG).show();
            ex.getStackTrace();

        }

        setListAdapter(resultListAdapter);

    }

    /**
     * Returns the items found and writes the items found to an arraylist.
     * @return
     */
    private ArrayList<SearchResultModel> itemsFound(Cursor cursor, String itemName, String     itemDescription, int type) {
        // ArrayList<String> list = new ArrayList<String>();

        if (cursor.moveToFirst()) {
            do {
                searchResultList.add(new SearchResultModel(itemName, itemDescription, type, ICON));
            } while (cursor.moveToNext());
        }
        cursor.close();

        return searchResultList;
    }


}

Надеюсь, что это поможет

Ответ 4

"Мой файл res/xml/searchable.xml(Примечание: мне пришлось создать папку" xml "в папке res, потому что ее не было. Я не думаю, что это должно иметь значение?"

Вы можете добавлять папки по мере необходимости, если вы следуете за указателями пространств имен xmls

Что касается поиска, я не верю, что minSdkVersion и targetSdkVersion являются правильными.

В соответствии с статьей Android, оставшейся обратной совместимостью, вы должны использовать

<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="15" />

<application>
...