我的第四天试图解决这个问题:(我正在尝试向我的应用栏添加搜索功能。在进程中,我需要获取searchManager.getSearchableInfo()
但它返回null,因此我无法获得我的搜索工作。我知道有类似的问题,但没有一个工作。
我迫切需要你的帮助!
摘要:
toolbar =(工具栏)findViewById(R.id.list_toolbar); setSupportActionBar(栏);
的AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="etchee.com.weightlifty">
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="25" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_app_logo"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<meta-data
android:name="android.app.default_searchable"
android:value=".Search.SearchResultsActivity">
</meta-data>
<activity
android:name=".Activity.MainActivity"
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=".data.DBviewer" />
<activity
android:name=".Search.SearchResultsActivity"
android:label="@string/input_event"
android:launchMode="singleTop">
<meta-data
android:name="android.app.default_searchable"
android:resource="@xml/searchable" />
</activity>
<activity android:name=".Activity.ListActivity"
android:theme="@style/Theme.AppCompat.Light.NoActionBar">
<meta-data
android:name="android.app.default_searchable"
android:value=".Search.SearchResultsActivity" />
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
</activity>
<provider
android:name=".Search.SuggestionProvider"
android:authorities="suggestionProviderAuthority"
android:syncable="false" />
<activity android:name=".Activity.EditEventActivity" />
<activity android:name=".Activity.ChooseEventActivity" />
<provider
android:name=".data.DataProvider"
android:authorities="etchee.com.weightlifty"
android:exported="false" />
</application>
</manifest>
来自ListActivity.java
的与选项相关的代码:
private void deleteOptionRed(Menu menu) {
//set delete menu text to red color
MenuItem delete_all_events = menu.findItem(R.id.menu_delete_all_events);
SpannableString string = new SpannableString(delete_all_events.getTitle());
string.setSpan(
new ForegroundColorSpan(ContextCompat.getColor(ListActivity.this, R.color.colorPrimary)),
0,
string.length(),
Spanned.SPAN_PRIORITY);
delete_all_events.setTitle(string);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
deleteOptionRed(menu);
return super.onPrepareOptionsMenu(menu);
}
/**
* When creating the option, define the searchView.
* @param menu menu layout
* @return true
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_list, menu);
searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchView = (SearchView) menu.findItem(R.id.action_search_button).getActionView();
ComponentName componentName = new ComponentName(getApplicationContext(), ListActivity.class);
//checking logger
if (searchManager.getSearchableInfo(componentName) == null) {
throw new IllegalArgumentException(TAG + ": getSearchableInfo() returns null. " +
"Cannot start search");
}
//Get searchableInfo Object created from the searchable.xml config file
searchView.setSearchableInfo(searchManager.getSearchableInfo(componentName));
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_search_button:
// Intent intent = new Intent(Intent.ACTION_SEARCH);
// intent.putExtra(SearchManager.QUERY, "Test");
onSearchRequested();
// startActivity(intent);
break;
case R.id.menu_delete_all_events:
int numOfDeletedRows = deleteEventTable();
Toast.makeText(ListActivity.this, String.valueOf(numOfDeletedRows) + " deleted.",
Toast.LENGTH_SHORT).show();
break;
case R.id.menu_insert_event:
event_insertDummyValues();
break;
case R.id.menu_view_tables:
Intent intent = new Intent(getApplicationContext(), DBviewer.class);
startActivity(intent);
break;
}
return super.onOptionsItemSelected(item);
}
menu_list,在ListActivity中用于从以下位置获取菜单资源:
<?xml version="1.0" encoding="utf-8"?>
<item android:id="@+id/action_search_button"
android:title="@string/search_events"
android:icon="@drawable/ic_add_list"
app:showAsAction="ifRoom|collapseActionView"
app:actionViewClass="android.support.v7.widget.SearchView" />
<item
android:title="@string/insert_event_values"
android:id="@+id/menu_insert_event"
app:showAsAction="never"
/>
<item android:title="@string/view_tables"
android:id="@+id/menu_view_tables"
app:showAsAction="never" />
<item
android:title="@string/delete_all_events"
android:id="@+id/menu_delete_all_events"
app:showAsAction="never" />
最后,我的 searchable.xml配置文件。 (它在res / xml下。我确定了。)
<?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/hint_search_events"
android:searchSuggestAuthority="@string/suggestion_provider_authority"
>
</searchable>
答案 0 :(得分:0)
试试这个:
创建一个菜单 search_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<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:title="@string/search"
android:icon="@drawable/search"
android:orderInCategory="100"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="always" />
</menu>
在列表活动中对此菜单进行充气
活动类:
`implements SearchView.OnQueryTextListener`
然后:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.search, menu);
final MenuItem item = menu.findItem(R.id.action_search);
MenuItemCompat.expandActionView(item);
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
searchView.setQueryHint(getString(R.string.search_orders));
searchView.setOnQueryTextListener(this);
return true;
}
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
if (newText.equals("")){
initProductCatalog();
return true;
}else{
final List<ProductItemObject> filteredModelList = filter(productItemObjects, newText);
itemsAdapter.notifyDataSetChanged();
mRecyclerView.setAdapter(itemsAdapter);
itemsAdapter.animateTo(filteredModelList);
mRecyclerView.scrollToPosition(0);
return true;
}
}
private List<ProductItemObject> filter(List<ProductItemObject> models, String query) {
query = query.toLowerCase();
final List<ProductItemObject> filteredModelList = new ArrayList<>();
if(query.equals("")) { return productItemObjects; }
for (ProductItemObject model : models) {
final String text = model.getName().toLowerCase();
if (text.contains(query)) {
filteredModelList.add(model);
}
}
return filteredModelList;
}
现在,你的适配器就是魔术发生的地方:
请记住用您自己的变量组件替换它们。我也在这里使用RecyclerViewer,而不是旧的列表视图:
适配器
public class ProductItemsAdapter extends RecyclerView.Adapter<ProductViewHolder>{
private List<ProductItemObject> products;
private Context context;
public ProductItemsAdapter(List<ProductItemObject> products, Context context) {
this.products = products;
this.context = context;
}
@Override
public ProductViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.product_catalog_card, parent, false);
return new ProductViewHolder(view);
}
@Override
public void onBindViewHolder(ProductViewHolder holder, int position) {
holder.name.setText(products.get(position).getName());
holder.prices.setText(products.get(position).getPrice());
Picasso.with(context)
.load(products.get(position).getUrl())
.placeholder(R.drawable.fry_mate_cooking)
.centerCrop()
.resize(100, 100)
.error(R.drawable.product_sample)
.into(holder.image);
}
public ProductItemObject get(int position){
return products.get(position);
}
public void remove(int position){
products.remove(position);
notifyDataSetChanged();
}
@Override
public int getItemCount() {
return products.size();
}
public ProductItemObject getItem(int position){
return products.get(position);
}
public void setModels(List<ProductItemObject> orders){
products = new ArrayList<>(orders);
}
public void animateTo(List<ProductItemObject> models) {
applyAndAnimateRemovals(models);
applyAndAnimateAdditions(models);
applyAndAnimateMovedItems(models);
}
private void applyAndAnimateRemovals(List<ProductItemObject> newModels) {
for (int i = products.size() - 1; i >= 0; i--) {
final ProductItemObject model = products.get(i);
if (!newModels.contains(model)) {
removeItem(i);
}
}
}
private void applyAndAnimateAdditions(List<ProductItemObject> newModels) {
for (int i = 0, count = newModels.size(); i < count; i++) {
final ProductItemObject model = newModels.get(i);
if (!products.contains(model)) {
addItem(i, model);
}
}
}
private void applyAndAnimateMovedItems(List<ProductItemObject> newModels) {
for (int toPosition = newModels.size() - 1; toPosition >= 0; toPosition--) {
final ProductItemObject model = newModels.get(toPosition);
final int fromPosition = products.indexOf(model);
if (fromPosition >= 0 && fromPosition != toPosition) {
moveItem(fromPosition, toPosition);
}
}
}
private ProductItemObject removeItem(int position) {
final ProductItemObject model = products.remove(position);
notifyItemRemoved(position);
return model;
}
private void addItem(int position, ProductItemObject model) {
products.add(position, model);
notifyItemInserted(position);
}
private void moveItem(int fromPosition, int toPosition) {
final ProductItemObject model = products.remove(fromPosition);
products.add(toPosition, model);
notifyItemMoved(fromPosition, toPosition);
}
}
照常创建视图
public class ProductViewHolder extends RecyclerView.ViewHolder{
@BindView(R.id.product_image)
CircleImageView image;
@BindView(R.id.product_name)
SalesLifeTextView name;
@BindView(R.id.price)
SalesLifeTextView prices;
@BindView(R.id.buy)
CircleImageView buy;
public ProductViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
最后,在我的案例中创建一个java类(POJO
)来表示 ProductItemObject 。
此代码可让您只使用操作栏搜索图标搜索列表中的项目。
这是很多代码,但一旦你开始工作,你会很高兴你做到了!