Мне нужно создать SearchView
из моего arrayList<String>
и показать предложения в раскрывающемся списке так же, как это
Я ищу руководства, которые шаг за шагом объясняют, как создать SearchView
панель действий.
я прочитал документацию и следую примеру Google, но мне это не пригодилось.
Я создал поиск
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/action_search"
android:title="Search"
android:icon="@android:drawable/ic_menu_search"
android:showAsAction="always"
android:actionViewClass="android.widget.SearchView" />
</menu>`
Но я не знаю, как задать параметры массива строк. Я попытался получить результат в другом действии, но не работал.
Ответы:
Чтобы найти решение для этого, потребовалось время, но мы обнаружили, что это самый простой способ заставить его работать так, как вы описываете. Могут быть более эффективные способы сделать это, но, поскольку вы еще не опубликовали свой код активности, мне придется импровизировать и предположить, что у вас есть такой список в начале вашей активности:
private List<String> items = db.getItems();
ExampleActivity.java
private List<String> items; 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 String[] columns = new String[] { "_id", "text" }; Object[] temp = new Object[] { 0, "default" }; MatrixCursor cursor = new MatrixCursor(columns); for(int i = 0; i < items.size(); i++) { temp[0] = i; temp[1] = items.get(i); cursor.addRow(temp); } // SearchView SearchManager manager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); final SearchView search = (SearchView) menu.findItem(R.id.search).getActionView(); search.setSuggestionsAdapter(new ExampleAdapter(this, cursor, items)); } }
Теперь вам нужно создать адаптер, расширенный из
CursorAdapter
:ExampleAdapter.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(items.get(cursor.getPosition())); } @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; } }
Лучший способ сделать это - если данные вашего списка взяты из базы данных, вы можете передать
Cursor
возвращаемые функциями базы данных напрямуюExampleAdapter
и использовать соответствующий селектор столбцов для отображения текста столбца в указанномTextView
в адаптере.Обратите внимание: при импорте
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 / searchchable.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
для вашего проекта.источник
search.setSearchableInfo(manager.getSearchableInfo(getComponentName()));
называется дважды вonCreateOptionsMenu()
иloadHistory()
методах. Поэтому я создаю глобальные переменные SearchView и SearchManager и вызываю их толькоgetSearchableInfo()
один разonCreateOptionsMenu()
. И мой список предложений теперь работает отлично. Предлагаю вам пересмотреть свой код.Если у кого-то еще есть nullptr в переменной searchview, я обнаружил, что настройка элемента немного отличается:
старый:
android:showAsAction="ifRoom" android:actionViewClass="android.widget.SearchView"
новый:
app:showAsAction="ifRoom|collapseActionView" app:actionViewClass="androidx.appcompat.widget.SearchView"
до Android x:
app:showAsAction="ifRoom|collapseActionView" app:actionViewClass="android.support.v7.widget.SearchView"
Для получения дополнительной информации обновленная документация находится здесь .
источник
app:actionViewClass="androidx.appcompat.widget.SearchView"
для androidxSearchDialog или SearchWidget?
Когда дело доходит до реализации функции поиска , в официальной документации для разработчиков Android предлагается два подхода .
Вы можете использовать SearchDialog или SearchWidget .
Я собираюсь объяснить реализацию функции поиска с помощью SearchWidget.
Как это сделать с виджетом поиска?
Я объясню функции поиска в RecyclerView с помощью SearchWidget. Это довольно просто.
Просто выполните эти 5 простых шагов
1) Добавить в меню пункт searchView
Вы можете добавить,
SearchView
можно добавить, какactionView
в меню, используя<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="rohksin.com.searchviewdemo.MainActivity"> <item android:id="@+id/searchBar" app:showAsAction="always" app:actionViewClass="android.support.v7.widget.SearchView" /> </menu>
2) Настройте текст подсказки SerchView, слушателя и т. Д.
Вы должны инициализировать SearchView в
onCreateOptionsMenu(Menu menu)
методе.@Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); MenuItem searchItem = menu.findItem(R.id.searchBar); SearchView searchView = (SearchView) searchItem.getActionView(); searchView.setQueryHint("Search People"); searchView.setOnQueryTextListener(this); searchView.setIconified(false); return true; }
3) Реализуйте SearchView.OnQueryTextListener в своей деятельности
OnQueryTextListener
имеет два абстрактных методаonQueryTextSubmit(String query)
onQueryTextChange(String newText
Итак, ваш каркас Activity будет выглядеть так
YourActivity extends AppCompatActivity implements SearchView.OnQueryTextListener{ public boolean onQueryTextSubmit(String query) public boolean onQueryTextChange(String newText) }
4) Реализуйте SearchView.OnQueryTextListener
Вы можете предоставить реализацию для таких абстрактных методов, как этот
public boolean onQueryTextSubmit(String query) { // This method can be used when a query is submitted eg. creating search history using SQLite DB Toast.makeText(this, "Query Inserted", Toast.LENGTH_SHORT).show(); return true; } @Override public boolean onQueryTextChange(String newText) { adapter.filter(newText); return true; }
5) Напишите метод фильтрации в вашем адаптере RecyclerView.
Самая важная часть. Вы можете написать свою собственную логику для выполнения поиска.
Вот мой. Этот фрагмент показывает список Name, который содержит текст, введенный в
SearchView
public void filter(String queryText) { list.clear(); if(queryText.isEmpty()) { list.addAll(copyList); } else { for(String name: copyList) { if(name.toLowerCase().contains(queryText.toLowerCase())) { list.add(name); } } } notifyDataSetChanged(); }
Соответствующая ссылка:
Полный рабочий код SearchView с базой данных SQLite в этом музыкальном приложении
источник
За
Searchview
использования этого кодаДля XML
<android.support.v7.widget.SearchView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/searchView"> </android.support.v7.widget.SearchView>
В вашем фрагменте или действии
package com.example.user.salaryin; import android.app.ProgressDialog; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.view.MenuItemCompat; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.SearchView; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.Toast; import com.example.user.salaryin.Adapter.BusinessModuleAdapter; import com.example.user.salaryin.Network.ApiClient; import com.example.user.salaryin.POJO.ProductDetailPojo; import com.example.user.salaryin.Service.ServiceAPI; import java.util.ArrayList; import java.util.List; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; public class OneFragment extends Fragment implements SearchView.OnQueryTextListener { RecyclerView recyclerView; RecyclerView.LayoutManager layoutManager; ArrayList<ProductDetailPojo> arrayList; BusinessModuleAdapter adapter; private ProgressDialog pDialog; GridLayoutManager gridLayoutManager; SearchView searchView; public OneFragment() { // Required empty public constructor } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.one_fragment,container,false); pDialog = new ProgressDialog(getActivity()); pDialog.setMessage("Please wait..."); searchView=(SearchView)rootView.findViewById(R.id.searchView); searchView.setQueryHint("Search BY Brand"); searchView.setOnQueryTextListener(this); recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView); layoutManager = new LinearLayoutManager(this.getActivity()); recyclerView.setLayoutManager(layoutManager); gridLayoutManager = new GridLayoutManager(this.getActivity().getApplicationContext(), 2); recyclerView.setLayoutManager(gridLayoutManager); recyclerView.setHasFixedSize(true); getImageData(); // Inflate the layout for this fragment //return inflater.inflate(R.layout.one_fragment, container, false); return rootView; } private void getImageData() { pDialog.show(); ServiceAPI service = ApiClient.getRetrofit().create(ServiceAPI.class); Call<List<ProductDetailPojo>> call = service.getBusinessImage(); call.enqueue(new Callback<List<ProductDetailPojo>>() { @Override public void onResponse(Call<List<ProductDetailPojo>> call, Response<List<ProductDetailPojo>> response) { if (response.isSuccessful()) { arrayList = (ArrayList<ProductDetailPojo>) response.body(); adapter = new BusinessModuleAdapter(arrayList, getActivity()); recyclerView.setAdapter(adapter); pDialog.dismiss(); } else if (response.code() == 401) { pDialog.dismiss(); Toast.makeText(getActivity(), "Data is not found", Toast.LENGTH_SHORT).show(); } } @Override public void onFailure(Call<List<ProductDetailPojo>> call, Throwable t) { Toast.makeText(getActivity(), t.getMessage(), Toast.LENGTH_SHORT).show(); pDialog.dismiss(); } }); } /* @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { getActivity().getMenuInflater().inflate(R.menu.menu_search, menu); MenuItem menuItem = menu.findItem(R.id.action_search); SearchView searchView = (SearchView) MenuItemCompat.getActionView(menuItem); searchView.setQueryHint("Search Product"); searchView.setOnQueryTextListener(this); }*/ @Override public boolean onQueryTextSubmit(String query) { return false; } @Override public boolean onQueryTextChange(String newText) { newText = newText.toLowerCase(); ArrayList<ProductDetailPojo> newList = new ArrayList<>(); for (ProductDetailPojo productDetailPojo : arrayList) { String name = productDetailPojo.getDetails().toLowerCase(); if (name.contains(newText) ) newList.add(productDetailPojo); } adapter.setFilter(newList); return true; } }
В классе адаптера
public void setFilter(List<ProductDetailPojo> newList){ arrayList=new ArrayList<>(); arrayList.addAll(newList); notifyDataSetChanged(); }
источник