Android Action Bar SearchView как автозаполнение?

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

Это возможно? Или мне нужно использовать собственное текстовое поле, а затем добавить к нему автозаполнение?


person Harsha M V    schedule 04.04.2013    source источник


Ответы (7)


Я использовал собственный AutoCompleteTextView и добавил его в панель действий.

введите здесь описание изображения

public class MainActivity extends Activity {

    private static final String[] COUNTRIES = new String[] { "Belgium",
            "France", "France_", "Italy", "Germany", "Spain" };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ActionBar actionBar = getActionBar();
        actionBar.setDisplayHomeAsUpEnabled(true);
        actionBar.setDisplayShowCustomEnabled(true);
        // actionBar.setDisplayShowTitleEnabled(false);
        // actionBar.setIcon(R.drawable.ic_action_search);

        LayoutInflater inflator = (LayoutInflater) this
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View v = inflator.inflate(R.layout.actionbar, null);

        actionBar.setCustomView(v);

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_dropdown_item_1line, COUNTRIES);
        AutoCompleteTextView textView = (AutoCompleteTextView) v
                .findViewById(R.id.editText1);
        textView.setAdapter(adapter);

    }

}

и ваш макет:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Action Bar:"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textColor="#FFFFFF" />

    <AutoCompleteTextView
        android:id="@+id/editText1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:imeOptions="actionSearch"
        android:inputType="textAutoComplete|textAutoCorrect"
        android:textColor="#FFFFFF" >

        <requestFocus />
    </AutoCompleteTextView>

</LinearLayout>

Отредактировано:

Пожалуйста, проверьте это и это ссылка может вам помочь. здесь.

person Dhaval Parmar    schedule 08.04.2013
comment
как я могу добавить источник данных в качестве базы данных? с ограниченной строкой это проще. но у меня около 250 и еще один список до 4000 строк - person Harsha M V; 08.04.2013
comment
Хорошо, но это не SearchView. Мне действительно нужен значок поиска слева и значок X справа, когда текст есть. - person tasomaniac; 18.07.2013
comment
@tasomaniac: то, что вы хотите, также не является представлением поиска ... независимо от того, сочетаете ли вы приведенный выше код и этот код ----› stackoverflow.com /a/6355178/1168654 - person Dhaval Parmar; 19.07.2013
comment
Я решил свою проблему. На самом деле SearchView имеет встроенную функцию автозаполнения, но ему нужен контент-провайдер. Вместо того, чтобы устанавливать AutoCompleteTextView и его необходимые функции, я просто создаю ContentProvider, который только запрашивает, а не вставляет, не удаляет. И это решается. - person tasomaniac; 19.07.2013
comment
Можно ли добавить два виджета поиска в одну и ту же панель действий? - person Elyes Jlassi; 30.10.2014
comment
Где панель действий? - person Rasshu; 07.07.2016

Поэтому мне просто пришлось сделать это для версии v7, и я был встревожен, обнаружив, что не могу просто установить адаптер с помощью ArrayAdapter.

Я не хотел использовать стандартный AutoCompleteTextView (как это делает главный комментатор здесь), потому что тогда вы упускаете ряд привлекательных функций SearchView, таких как маленький значок поиска и кнопка x.

Итак, я расширил SearchView и получил следующее:

public class ArrayAdapterSearchView extends SearchView {

private SearchView.SearchAutoComplete mSearchAutoComplete;

public ArrayAdapterSearchView(Context context) {
    super(context);
    initialize();
}

public ArrayAdapterSearchView(Context context, AttributeSet attrs) {
    super(context, attrs);
    initialize();
}

public void initialize() {
    mSearchAutoComplete = (SearchAutoComplete) findViewById(android.support.v7.appcompat.R.id.search_src_text);
    this.setAdapter(null);
    this.setOnItemClickListener(null);
}

@Override
public void setSuggestionsAdapter(CursorAdapter adapter) {
    // don't let anyone touch this
}

public void setOnItemClickListener(OnItemClickListener listener) {
    mSearchAutoComplete.setOnItemClickListener(listener);
}

public void setAdapter(ArrayAdapter<?> adapter) {
    mSearchAutoComplete.setAdapter(adapter);
}

public void setText(String text) {
    mSearchAutoComplete.setText(text);
}

}

Вы можете использовать это в своем меню xml для панели действий следующим образом:

<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:icon="@android:drawable/ic_menu_add"
    android:title="TITLE"
    app:actionViewClass="com.yourpackage.ArrayAdapterSearchView"
    app:showAsAction="ifRoom|collapseActionView"/>

</menu>

Вы также можете добавить функцию щелчка в список автозаполнения (например, установить текст в EditText):

MenuItem searchItem = menu.findItem(R.id.action_search);
final ArrayAdapterSearchView searchView = (ArrayAdapterSearchView)searchItem.getActionView();
searchView.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

        searchView.setText(adapter.getItem(position).toString());

    }
});

А вот аналогичный вариант для обычного старого android.widget.SearchView:

public class ArrayAdapterSearchView extends SearchView {

private AutoCompleteTextView mSearchAutoComplete;

public ArrayAdapterSearchView(Context context) {
    super(context);
    initialize();
}

public ArrayAdapterSearchView(Context context, AttributeSet attrs) {
    super(context, attrs);
    initialize();
}

public void initialize() {
    mSearchAutoComplete = (AutoCompleteTextView) findViewById(getResources().getIdentifier("android:id/search_src_text", null, null));
    setAutoCompleSuggestionsAdapter(null);
    setOnItemClickListener(null);
}

@Override
public void setSuggestionsAdapter(CursorAdapter adapter) {
    throw new UnsupportedOperationException("Please use setAutoCompleSuggestionsAdapter(ArrayAdapter<?> adapter) instead");
}

public void setOnItemClickListener(AdapterView.OnItemClickListener listener) {
    mSearchAutoComplete.setOnItemClickListener(listener);
}

public void setAutoCompleSuggestionsAdapter(ArrayAdapter<?> adapter) {
    mSearchAutoComplete.setAdapter(adapter);
}

public void setText(String text) {
    mSearchAutoComplete.setText(text);
}

}
person Community    schedule 15.11.2013
comment
Мне понравилась эта идея, и я реализовал ее, но у меня возникла проблема. Я вижу результаты автозаполнения, но когда я нажимаю на элемент, строка элемента не выделяется. Я имею в виду, что он не отображается в текстовом представлении, как только я его выбрал. Можете ли вы дать больше информации об этом? Или рабочий фрагмент кода? - person shaktiman_droid; 09.12.2013
comment
Затем мне придется добавить новый метод (setText) в мой класс customSearchView. - person shaktiman_droid; 09.12.2013
comment
Да: public void setText (текст строки) { mSearchAutoComplete.setText (текст); } - person ; 10.12.2013
comment
Почему бы не использовать функцию предложений по умолчанию? как здесь: developer.android.com/guide/topics/search / - person vedant; 28.04.2015
comment
Спасибо; Я использую этот подход в сочетании с onQueryTextChange() (SearchView.OnQueryTextListener) и все работает довольно быстро. - person Jonik; 28.04.2015
comment
@vedant1811 Может быть, потому что люди не хотят использовать CursorAdapter. - person Mussa; 05.09.2015
comment
@ Александр, я новичок в Android, и я применил ваш код, но у меня есть список строк и элемент поиска, как настроить адаптер для просмотра и заполнить список результатов из моего списка строк? - person Asmaa Rashad; 09.06.2016
comment
@AsmaaRashad, используйте метод setAdapter для ArrayAdapterSearchView searchView. Как создать адаптер из массива строк, вы можете найти здесь - stackoverflow.com/a/12109813/2308720 - person Oleksandr; 09.06.2016

Вот альтернативный метод с использованием CursorAdapter:

ПримерActivity.java

private Menu menu;

@Override
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public boolean onCreateOptionsMenu(Menu menu) {

    getMenuInflater().inflate(R.menu.example, menu);

    this.menu = menu;

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {

        SearchManager manager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);

        SearchView search = (SearchView) menu.findItem(R.id.search).getActionView();

        search.setSearchableInfo(manager.getSearchableInfo(getComponentName()));

        search.setOnQueryTextListener(new OnQueryTextListener() { 

            @Override 
            public boolean onQueryTextChange(String query) {

                loadHistory(query);

                return true; 

            } 

        });

    }

    return true;

}

// History
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void loadHistory(String query) {

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {

        Cursor cursor = db.rawQuery("SELECT * FROM items", null); // Example database query

        SearchManager manager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);

        final SearchView search = (SearchView) menu.findItem(R.id.search).getActionView();

        search.setSearchableInfo(manager.getSearchableInfo(getComponentName()));

        search.setSuggestionsAdapter(new ExampleAdapter(this, cursor, items));

    }

}

Теперь вам нужно создать адаптер, расширенный от CursorAdapter:

ПримерAdapter.java

public class ExampleAdapter extends CursorAdapter {

    private List<String> items;

    private TextView text;

    public ExampleAdapter(Context context, Cursor cursor, List<String> items) {

        super(context, cursor, false);

        this.items = items;

    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {

        text.setText(cursor.getString(cursor.getColumnIndex("text"))); // Example column index

    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {

        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View view = inflater.inflate(R.layout.item, parent, false);

        text = (TextView) view.findViewById(R.id.text);

        return view;

    }

}

Обратите внимание: при импорте CursorAdapter не импортируйте версию поддержки Android, вместо этого импортируйте стандартную android.widget.CursorAdapter.

Адаптер также потребует пользовательского макета:

res/layout/item.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <TextView
        android:id="@+id/item"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>

Теперь вы можете настраивать элементы списка, добавляя в макет дополнительные текстовые или графические представления и заполняя их данными в адаптере. Теперь вам нужен пункт меню SearchView:

res/menu/example.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/search"
        android:title="@string/search"
        android:showAsAction="ifRoom"
        android:actionViewClass="android.widget.SearchView" />

</menu>

Затем создайте конфигурацию с возможностью поиска:

res/xml/searchable.xml

<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/search"
    android:hint="@string/search" >
</searchable>

Наконец, добавьте это в соответствующий тег активности в файле манифеста:

AndroidManifest.xml

<intent-filter>
    <action android:name="android.intent.action.SEARCH" />
</intent-filter>

<meta-data
    android:name="android.app.default_searchable"
    android:value="com.example.ExampleActivity" />
<meta-data
    android:name="android.app.searchable"
    android:resource="@xml/searchable" />

Обратите внимание: строка @string/search, используемая в примерах, должна быть определена в values/strings.xml, также не забудьте обновить ссылку на com.example для вашего проекта.

Вот оригинальный учебник для справки:

http://tpbapp.com/android-development/android-action-bar-searchview-tutorial

person tpbapp    schedule 16.03.2014
comment
БЛАГОДАРНОСТЬ !!! сделал мой день :) Одно изменение для меня, я собираюсь получить данные, запросив их у сервера, а затем обновить SearchView с новым адаптером. Даст вам знать, если это сработает. Еще раз спасибо ! - person Shirane85; 20.05.2014
comment
@ Shirane85 Эй, нет проблем, надеюсь, все пройдет хорошо. Этот метод, как мне кажется, предназначен для отображения результатов из базы данных из-за требуемого формата данных Cursor, который является стандартным форматом для обработки данных базы данных. Я адаптировал его здесь также для использования с ArrayList, чтобы в целом быть более совместимым с типичным набором данных, однако это, конечно, ограничит производительность, особенно при работе с большими объемами данных. - person tpbapp; 20.05.2014
comment
Ну у меня проблема в конце концов. При вызове сети после ввода буквы в поле поиска я возвращаю true в onQueryTextChange. Пока все хорошо и ничего не происходит. Но когда ответ перезванивает, и я выполняю search.setSuggestionsAdapter(), все равно ничего не происходит, и всплывающее окно предложения не отображается. Странно то, что после заполнения второй буквы сразу показывает предложение первого адаптера. Нужна помощь... - person Shirane85; 22.05.2014
comment
@ Shirane85 это происходит, например, когда вы создаете статический список примеров вместо загрузки с веб-ресурса? Похоже, вам нужно будет превратить это в другой вопрос и опубликовать свой код, так как у меня этого не происходит. Если вы опубликуете вопрос, пожалуйста, ссылку отсюда, и я постараюсь помочь. - person tpbapp; 22.05.2014
comment
Код глючит. Если он используется как есть, он показывает странные (или, скорее, старые) предложения. Решение состоит в том, чтобы каждый раз создавать и устанавливать новый адаптер и всегда вызывать notifyDataSetChanged. - person 0101100101; 22.07.2015
comment
Ссылка на оригинальное руководство для справки: is Dead - person Kenny Dabiri; 28.11.2019

Я также столкнулся с этой проблемой для представления автоматического завершения поиска и исправил ее без использования какого-либо дополнительного макета и представления автоматического завершения текста, есть класс под названием SearchAutoComplete. Я использовал это для достижения функции автоматического завершения, просто поместил простой адаптер списка, который содержит ArrayList элементов, чтобы предложить их с представлением поиска. Установите адаптер на свой SearchAutoComplete, и функция автозаполнения будет работать ниже, это мой код. Помните, что вам не нужно добавлять какой-либо пользовательский макет. Просто замените метод onCreateOptionsMenu(...) моим кодом:

    @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);

MenuItem searchItem = menu.findItem(R.id.search);
SearchView mSearchView = (SearchView) MenuItemCompat.getActionView(searchItem);

SearchAutoComplete searchAutoComplete = (SearchAutoComplete)     mSearchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_dropdown_item_1line, itemArrayList);
searchAutoComplete.setAdapter(adapter);

SearchManager searchManager =
(SearchManager) getSystemService(this.SEARCH_SERVICE);
mSearchView.setSearchableInfo(
searchManager.getSearchableInfo(getComponentName()));
return true;
}

При нажатии на предложенный элемент элемент должен появиться в представлении поиска, поэтому добавьте приведенный ниже код сразу после того, как вы установите адаптер для searchAutoComplete внутри метода onCreateOptionmenu(...)

  searchAutoComplete.setOnItemClickListener(new OnItemClickListener() {

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position,
    long id) {
    // TODO Auto-generated method stub

    String searchString=(String)parent.getItemAtPosition(position);
    searchAutoComplete.setText(""+searchString);
    Toast.makeText(MainActivity.this, "you clicked "+searchString, Toast.LENGTH_LONG).show();

    }
    });
person HAXM    schedule 14.11.2015
comment
Я пробовал это, но получил это исключение: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.SearchView$SearchAutoComplete.setTextColor(int)' on a null object reference. Похоже, что searchAutoComplete всегда возвращает для меня значение null. Любая идея, почему это? - person VIN; 11.04.2016
comment
Привет @HAXM ... это сработало для меня ... но я получаю список предложений на сероватом фоне, как сделать это на белом фоне? - person SoulRayder; 07.01.2017
comment
@SoulRayder, измените тему своей панели инструментов, если вы не используете панель инструментов, используйте панель инструментов, потому что без использования панели инструментов вы должны изменить тему своей деятельности, что изменит внешний вид активности - person HAXM; 07.01.2017

Да, это возможно. Создайте таблицу (например, в базе данных SQLiteDatabase) для ваших предложений и отформатируйте таблицу с необходимыми столбцами.

см. эту ссылку

person Arun C    schedule 04.04.2013
comment
можно ли вместо этого добавить автозаполнение? - person Harsha M V; 04.04.2013
comment
См. это Это дает объяснение того, как реализовать авто -Полный для просмотра поиска. - person buggydroid; 15.04.2013

Вы можете сделать это с помощью CursorAdapter, например:

MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);

searchView.setSuggestionsAdapter(adapter);
person Community    schedule 14.11.2013

    SearchAutoComplete searchAutoComplete = mSearchView.findViewById(androidx.appcompat.R.id.search_src_text);

для версии androidx

person Akgun Studio    schedule 10.05.2019