在我的应用程序中,我在SearchView
中有一个Toolbar
。
当用户单击搜索图标时,SearchView会展开并开始输入。搜索查询按标题过滤RecyclerView
列表。这一切都很好。
但是,当我对RecyclerView
项之一执行OnLongClick操作时,筛选器功能停止工作。
我在每个RecyclerView
持有者上都附加了一个OnClickListener和OnLongClickListener,但是只有OnLongClick操作阻止了SearchView
进行过滤。我不明白为什么。我尝试重新实例化SearchView
并将RecyclerView
重置为无效。
这是我的代码:
为了节省空间,已删除了不影响SearchView的功能。
MainActivity.java
public class MainActivity extends AppCompatActivity {
//LONG CLICK ACTION MODE VARIABLES
boolean isInActionMode = false;
TextView selectedCounterText;
//SEARCH BAR
SearchView searchView;
//INSERT DIALOG TEXTVIEWS
EditText editTitle, editCategory, editSignifier, editDate, editRecurs, editDetails;
Button btnCreate, btnCancel;
RecyclerView recyclerView;
RecyclerView.LayoutManager layoutManager;
CardAdapter adapter;
Toolbar toolbar;
ArrayList<Bullet> bullets = new ArrayList<>();
ArrayList<Bullet> selectedBullets = new ArrayList<>();
int counter = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
//SET DEFAULT VIEW STATES
selectedCounterText = (TextView) findViewById(R.id.selected_counter);
appName = (TextView) findViewById(R.id.app_name);
selectedCounterText.setVisibility(View.GONE);
appName.setVisibility(View.VISIBLE);
noBulletsMessage = (TextView) findViewById(R.id.noBullets_message);
noBulletsMessage.setVisibility(View.GONE);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//RECYCLERVIEW PROPERTIES
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setHasFixedSize(true);
//ACTION MODE ON LONG CLICK VIEW STATES
selectedCounterText = (TextView) findViewById(R.id.selected_counter);
selectedCounterText.setVisibility(View.GONE);
//ADAPTER
adapter = new CardAdapter(this, bullets);
//RETRIEVE DATA
retrieveData();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_activity_main, menu);
//SEARCH
final MenuItem searchItem = menu.findItem(R.id.item_search);
searchView = (SearchView) searchItem.getActionView();
searchView.setIconifiedByDefault(true);
searchView.setOnCloseListener(new SearchView.OnCloseListener() {
@Override
public boolean onClose() {
return false;
}
});
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String query) {
//FILTER AS YOU TYPE
adapter.getFilter().filter(query);
return false;
}
});
return true;
}
@Override
protected void onResume() {
super.onResume();
retrieveData();
}
/**
* @param item
* @return This method includes behavior for all action toolbar menu items: Add, search, edit,
* and delete.
* <p>
* It detects which button is pressed and performs the appropriate action.
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
//IF HOME (BACK ARROW) IS PRESSED
} else if (item.getItemId() == android.R.id.home) {
clearActionMode();
adapter.notifyDataSetChanged();
}
return true;
}
public void clearActionMode() {
isInActionMode = false;
toolbar.getMenu().clear();
toolbar.inflateMenu(R.menu.menu_activity_main);
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
selectedCounterText.setVisibility(View.GONE);
appName.setVisibility(View.VISIBLE);
selectedCounterText.setText("0 Item(s) Selected");
counter = 0;
selectedBullets.clear();
}
@Override
public void onBackPressed() {
if (isInActionMode) {
clearActionMode();
adapter.notifyDataSetChanged();
} else {
super.onBackPressed();
}
}
}
CardHolder.java
public CardHolder(final View itemView, final MainActivity mainActivity) {
super(itemView);
signifier_img = (ImageView) itemView.findViewById(R.id.img_id);
titleText = (TextView) itemView.findViewById(R.id.title);
categoryText = (TextView) itemView.findViewById(R.id.category);
cardView = (CardView) itemView.findViewById(R.id.bulletCardView);
checkBox = (CheckBox) itemView.findViewById(R.id.check_list_item);
this.mainActivity = mainActivity;
//CLICK LISTENERS
cardView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
mainActivity.toolbar.getMenu().clear();
mainActivity.toolbar.inflateMenu(R.menu.menu_action_mode);
mainActivity.selectedCounterText.setVisibility(View.VISIBLE);
mainActivity.appName.setVisibility(View.GONE);
mainActivity.isInActionMode = true;
mainActivity.adapter.notifyDataSetChanged();
mainActivity.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
return true;
}
});
cardView.setOnClickListener(this);
checkBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mainActivity.prepareSelection(view, getAdapterPosition());
}
});
}
@Override
public void onClick(View view) {
this.itemClickListener.onItemClick(view, getLayoutPosition());
}
public void setItemClickListener(ItemClickListener itemClick) {
this.itemClickListener = itemClick;
}
}
CardAdapter.java
public class CardAdapter extends RecyclerView.Adapter<CardHolder> implements Filterable {
Context context;
ArrayList<Bullet> bullets, filterList;
SearchFilter filter;
MainActivity mainActivity;
public CardAdapter(Context context, ArrayList<Bullet> bullets) {
this.context = context;
this.bullets = bullets;
this.filterList = bullets;
mainActivity = (MainActivity) context;
}
//INITIALIZE VIEWHOLDER
@Override
public CardHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//VIEW OBJ FROM XML
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_card_view, parent, false);
//HOLDER
CardHolder holder = new CardHolder(view, mainActivity);
return holder;
}
//BIND DATA TO VIEWS
@Override
public void onBindViewHolder(final CardHolder holder, int position) {
holder.signifier_img.setImageResource(R.drawable.asterisk_48px);
holder.titleText.setText(bullets.get(position).getTitle());
if (!mainActivity.isInActionMode) {
holder.checkBox.setVisibility(View.GONE);
} else {
holder.checkBox.setVisibility(View.VISIBLE);
holder.checkBox.setChecked(false);
}
//CARD CLICKED
holder.setItemClickListener(new ItemClickListener() {
@Override
public void onItemClick(View view, int position) {
//DISPLAY POPUP OF FULL INFO OF BULLET
//OPEN DETAIL VIEW
//PASS DATA TO VIEW
if (!mainActivity.isInActionMode) {
//CREATE INTENT
Intent intent = new Intent(context, DetailView.class);
//LOAD DATA TO INTENT
intent.putExtra("ID", bullets.get(position).getId());
intent.putExtra("TITLE", bullets.get(position).getTitle());
intent.putExtra("CATEGORY", bullets.get(position).getCategory());
intent.putExtra("SIGNIFIER", bullets.get(position).getSignifier());
intent.putExtra("DATE", bullets.get(position).getDate());
intent.putExtra("RECURS", bullets.get(position).getRecurs());
intent.putExtra("DETAILS", bullets.get(position).getDetails());
//START ACTIVITY
context.startActivity(intent);
} else {
//DO NOTHING
}
}
});
}
@Override
public int getItemCount() {
return bullets.size();
}
//RETURN FILTER OBJ
@Override
public Filter getFilter() {
if (filter == null) {
filter = new SearchFilter(filterList, this);
}
return filter;
}
}
SearchFilter.java
public class SearchFilter extends Filter {
CardAdapter adapter;
ArrayList<Bullet> filterList;
public SearchFilter(ArrayList<Bullet> filterList, CardAdapter adapter) {
this.adapter = adapter;
this.filterList = filterList;
}
//FILTER OCCURS HERE
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
//CHECK CONSTRAINT VALIDITY
if (constraint != null && constraint.length() > 0) {
//CHANGE TO UPPER
constraint = constraint.toString().toUpperCase();
//STORE FILTERED BULLETS
ArrayList<Bullet> filteredBullets = new ArrayList<>();
for (int i = 0; i < filterList.size(); i++) {
//CHECK
if (filterList.get(i).getTitle().toUpperCase().contains(constraint)) {
//ADD BULLET TO FILTERED BULLETS
filteredBullets.add(filterList.get(i));
}
}
results.count = filteredBullets.size();
results.values = filteredBullets;
} else {
results.count = filterList.size();
results.values = filterList;
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
adapter.bullets = (ArrayList<Bullet>) results.values;
//REFRESH RECYCLERVIEW
adapter.notifyDataSetChanged();
}
}
menu_activity_main.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/item_search"
android:icon="@drawable/ic_action_search"
android:title="Search..."
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="collapseActionView|ifRoom" />
<item
android:id="@+id/item_add"
android:icon="@drawable/ic_action_add2"
android:title="Add"
app:showAsAction="always" />
</menu>
我相信所有影响它的代码,但是如果还有其他需要告诉我。
这是堆栈跟踪:
我不太清楚这是什么意思,但是当我尝试在LongClick事件后过滤一些查询时,就会发生这种情况。
09-07 01:46:38.184 17027-17104 / com.curtiswhite.www.sqlitedatabaseforephemeris I / OpenGLRenderer:初始化的EGL版本1.4
09-07 01:47:40.066 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris E / SpannableStringBuilder:SPAN_EXCLUSIVE_EXCLUSIVE跨度不能为零长度
09-07 01:47:40.066 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris E / SpannableStringBuilder:SPAN_EXCLUSIVE_EXCLUSIVE跨度不能为零长度
09-07 01:47:45.036 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris E / SpannableStringBuilder:SPAN_EXCLUSIVE_EXCLUSIVE跨度不能为零长度
09-07 01:47:45.036 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris E / SpannableStringBuilder:SPAN_EXCLUSIVE_EXCLUSIVE跨度不能为零长度
09-07 01:47:45.991 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:非活动InputConnection上的beginBatchEdit
09-07 01:47:45.991 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:非活动InputConnection上的getSelectedText
09-07 01:47:46.003 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:在非活动InputConnection上的endBatchEdit
09-07 01:47:46.003 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:非活动InputConnection上的getTextBeforeCursor
09-07 01:47:46.015 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:非活动InputConnection上的getTextAfterCursor
09-07 01:47:46.022 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:非活动InputConnection上的beginBatchEdit
09-07 01:47:46.023 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:非活动InputConnection上的getSelectedText
09-07 01:47:46.023 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:在非活动InputConnection上的endBatchEdit
09-07 01:47:46.023 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:非活动InputConnection上的getTextBeforeCursor
09-07 01:47:46.024 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:非活动InputConnection上的getTextAfterCursor
09-07 01:47:46.027 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:非活动InputConnection上的beginBatchEdit
09-07 01:47:46.027 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:非活动InputConnection上的getSelectedText
09-07 01:47:46.027 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:在非活动InputConnection上的endBatchEdit
09-07 01:47:46.028 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:非活动InputConnection上的getTextBeforeCursor
09-07 01:47:46.030 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:非活动InputConnection上的getTextAfterCursor
09-07 01:47:46.062 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:非活动InputConnection上的beginBatchEdit
09-07 01:47:46.062 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:非活动InputConnection上的getSelectedText
09-07 01:47:46.062 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:在非活动InputConnection上的endBatchEdit
09-07 01:47:46.063 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:非活动InputConnection上的getTextBeforeCursor
09-07 01:47:46.063 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:非活动InputConnection上的getTextAfterCursor
最佳答案
我解决了这个问题。
事实证明,此问题是在对LongClick扩展新菜单时引起的。这导致SearchView
缩小(按预期方式),但是在按回(调用OnBackPressed)时,原始菜单会膨胀,但是放置的SearchView
上有一个尚未实例化的新菜单。
为了解决这个问题,我只是简单地调用OnCreateMenuOptions(toolbar.getMenu());。在onBackPressed方法中。这将重新实例化SearchView
,因此在菜单膨胀后它将再次运行。