arrayList<String>
からSearchView
を作成し、これと同じドロップダウンリストに提案を表示する必要があります
アクションバーで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);replaced s with i as s not used anywhere.
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/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
への参照を更新することを忘れないでください。
他の誰かがsearchview変数にnullptrを設定している場合、アイテムのセットアップが少し異なることがわかりました。
古い:
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"
詳細については、更新されたドキュメントが こちらにあります です。
検索機能の実装に関しては、Android開発者向け公式ドキュメントによる 2つの推奨されるアプローチ があります。
SearchDialogまたはSearchWidgetのいずれかを使用できます。
SearchWidgetを使用した検索機能の実装について説明します。
SearchWidgetを使用してRecyclerViewの検索機能を説明します。とても簡単です。
これらの5つの簡単な手順に従ってください
SearchView
を追加するには、メニューでactionView
として追加できます。
app:useActionClass = "Android.support.v7.widget.SearchView".
<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>
onCreateOptionsMenu(Menu menu)
メソッドでSearchViewを初期化する必要があります。
@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;
}
OnQueryTextListener
には2つの抽象メソッドがあります
onQueryTextSubmit(String query)
onQueryTextChange(String newText
アクティビティスケルトンは次のようになります
YourActivity extends AppCompatActivity implements SearchView.OnQueryTextListener{
public boolean onQueryTextSubmit(String query)
public boolean onQueryTextChange(String newText)
}
このような抽象メソッドの実装を提供できます
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;
}
最も重要な部分。独自のロジックを作成して、検索を実行できます。
これは私のものです。このスニペットは、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();
}
これでSQLiteデータベースを使用したSearchViewの完全な動作コード Music App
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();
}