Поддерживает ли ActionBarSherlock 4.2 варианты поиска для SearchView?

Месяц назад я вставил ActionBarSherlock 4.2 в свой проект. Я получил все, чтобы работать, кроме предложений поиска для моегоSearchView, То, как я создавал поисковые подсказки, использовалометод в документации Android.

Поддерживает ли ActionBarSherlock варианты поиска? Я пробовал копатьпроблема список на странице Github, но проблема кажется закрытой, но я могуКажется, что следит за обсуждением и понимает, действительно ли это решено или нет. Я думал, что некоторые из вас, ктоЯ использовал ActionBarSherlock, возможно, знает лучше.

Ответы на вопрос(3)

Решение Вопроса

Это нет. Но я нашел способ заставить его запросить ваш ContentProvider. Я посмотрел на источник SuggestionsAdapter из API 17, где выполняется запрос, и получил идею заменить этот метод. Также я обнаружил, что ActionbarSherlock 's SuggestionsAdapter не использует ваш SearchableInfo.

Отредактируйте com.actionbarsherlock.widget.SuggestionsAdapter в своем проекте ActionBarSherlock:

Добавить строку

private SearchableInfo searchable;

в конструктор добавить

this.searchable = mSearchable;

Замените метод getSuggestions на этот:

public Cursor getSuggestions(String query, int limit) {

    if (searchable == null) {
        return null;
    }

    String authority = searchable.getSuggestAuthority();
    if (authority == null) {
        return null;
    }

    Uri.Builder uriBuilder = new Uri.Builder()
            .scheme(ContentResolver.SCHEME_CONTENT)
            .authority(authority)
            .query("")  // TODO: Remove, workaround for a bug in Uri.writeToParcel()
            .fragment("");  // TODO: Remove, workaround for a bug in Uri.writeToParcel()

    // if content path provided, insert it now
    final String contentPath = searchable.getSuggestPath();
    if (contentPath != null) {
        uriBuilder.appendEncodedPath(contentPath);
    }

    // append standard suggestion query path
    uriBuilder.appendPath(SearchManager.SUGGEST_URI_PATH_QUERY);

    // get the query selection, may be null
    String selection = searchable.getSuggestSelection();
    // inject query, either as selection args or inline
    String[] selArgs = null;
    if (selection != null) {    // use selection if provided
        selArgs = new String[] { query };
    } else {                    // no selection, use REST pattern
        uriBuilder.appendPath(query);
    }

    if (limit > 0) {
        uriBuilder.appendQueryParameter("limit", String.valueOf(limit));
    }

    Uri uri = uriBuilder.build();

    // finally, make the query
    return mContext.getContentResolver().query(uri, null, selection, selArgs, null);
}

Теперь он запрашивает мой ContentProvider, но вылетает с адаптером по умолчанию, говоря, что нет layout_height, загружающего какой-то xml-файл из библиотеки поддержки. Таким образом, вы должны использовать пользовательские предложения AdAdter. Вот что сработало для меня:

import com.actionbarsherlock.widget.SearchView;

import android.app.SearchManager;
import android.app.SearchableInfo;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.support.v4.widget.CursorAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public final class DrugsSearchAdapter extends CursorAdapter
{
    private static final int QUERY_LIMIT = 50;

    private LayoutInflater inflater;
    private SearchView searchView;
    private SearchableInfo searchable;

    public DrugsSearchAdapter(Context context, SearchableInfo info, SearchView searchView)
    {
        super(context, null, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
        this.searchable = info;
        this.searchView = searchView;
        this.inflater = LayoutInflater.from(context);
    }

    @Override
    public void bindView(View v, Context context, Cursor c)
    {
        String name = c.getString(c.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_1));
        TextView namet = (TextView) v.findViewById(R.id.list_item_drug_name);
        namet.setText(name);

        String man = c.getString(c.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_2));
        TextView manuf = (TextView) v.findViewById(R.id.list_item_drug_manufacturer);
        manuf.setText(man);
    }

    @Override
    public View newView(Context arg0, Cursor arg1, ViewGroup arg2)
    {
        return this.inflater.inflate(R.layout.list_item_drug_search, null);
    }

    /**
     * Use the search suggestions provider to obtain a live cursor.  This will be called
     * in a worker thread, so it's OK if the query is slow (e.g. round trip for suggestions).
     * The results will be processed in the UI thread and changeCursor() will be called.
     */
    @Override
    public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
        String query = (constraint == null) ? "" : constraint.toString();
        /**
         * for in app search we show the progress spinner until the cursor is returned with
         * the results.
         */
        Cursor cursor = null;
        if (searchView.getVisibility() != View.VISIBLE
                || searchView.getWindowVisibility() != View.VISIBLE) {
            return null;
        }
        try {
            cursor = getSuggestions(searchable, query, QUERY_LIMIT);
            // trigger fill window so the spinner stays up until the results are copied over and
            // closer to being ready
            if (cursor != null) {
                cursor.getCount();
                return cursor;
            }
        } catch (RuntimeException e) {
        }
        // If cursor is null or an exception was thrown, stop the spinner and return null.
        // changeCursor doesn't get called if cursor is null
        return null;
    }

    public Cursor getSuggestions(SearchableInfo searchable, String query, int limit) {

        if (searchable == null) {
            return null;
        }

        String authority = searchable.getSuggestAuthority();
        if (authority == null) {
            return null;
        }

        Uri.Builder uriBuilder = new Uri.Builder()
                .scheme(ContentResolver.SCHEME_CONTENT)
                .authority(authority)
                .query("") 
                .fragment(""); 

        // if content path provided, insert it now
        final String contentPath = searchable.getSuggestPath();
        if (contentPath != null) {
            uriBuilder.appendEncodedPath(contentPath);
        }

        // append standard suggestion query path
        uriBuilder.appendPath(SearchManager.SUGGEST_URI_PATH_QUERY);

        // get the query selection, may be null
        String selection = searchable.getSuggestSelection();
        // inject query, either as selection args or inline
        String[] selArgs = null;
        if (selection != null) {    // use selection if provided
            selArgs = new String[] { query };
        } else {                    // no selection, use REST pattern
            uriBuilder.appendPath(query);
        }

        if (limit > 0) {
            uriBuilder.appendQueryParameter("limit", String.valueOf(limit));
        }

        Uri uri = uriBuilder.build();

        // finally, make the query
        return mContext.getContentResolver().query(uri, null, selection, selArgs, null);
    }

}

И установите этот адаптер в SearchView

searchView.setSuggestionsAdapter(new DrugsSearchAdapter(this, searchManager.getSearchableInfo(getComponentName()), searchView));
 Chris Lacy26 янв. 2013 г., 05:54
Большое спасибо за то, что нашли время написать этот замечательный ответ :)

Я нене знаю, если яЯ ошибся или я что-то изменил случайно, но приведенный выше ответ не работает, а ActionBarSherlock SuggestionsAdapter не работает. Все, что я получаю, это нулевые указатели в runQueryOnBackgroundThread. Он также никогда не входит в bindView и т. Д., Но все же удается отобразить результаты подсказок. Я думаю, что android.app.SearchManager как-то переопределяет ABS с помощью getSuggestions (), но я 'Я не уверен. Я'Я все еще пробую вещи ...

м тот, который открылвопрос GitHub за это. Он работает на ветке разработчика. Текущая версия (4.2) нене могу исправить. Это было полностью исправлено этимсовершить, но я бы предложил просто проверить ветку dev и попробовать ее.

 arne.jans06 мая 2013 г., 16:48
поскольку ветка dev в настоящее время кажется объединенной с master и впереди нее, fix-commit также находится в master, и использование master должно работать.

Ваш ответ на вопрос