Dans mon application, j'ai un SearchView
dans le Toolbar
.SearchView arrête le filtrage après l'action LongClick
Lorsque l'utilisateur clique sur l'icône de recherche, le SearchView se développe et l'utilisateur commence à taper. La requête de recherche filtre une liste RecyclerView
par titre. Tout cela fonctionne très bien.
Toutefois, la fonction de filtre cesse de fonctionner lorsque j'effectue une action OnLongClick sur l'un des éléments RecyclerView
.
I ont tous deux une OnClickListener et OnLongClickListener attachés à chaque support RecyclerView
, mais il est seulement l'action OnLongClick qui arrête le SearchView
de filtrage. Je ne comprends pas pourquoi. J'ai essayé de rétablir le SearchView
et de réinitialiser le RecyclerView
en vain.
Voici mon code:
Les fonctions qui ne touchent pas le SearchView ont été enlevées pour des raisons d'espace.
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>
Je crois que tout le code est qu'il affecte, mais s'il y a autre chose dont vous avez besoin laissez-moi savoir.
Voici le Stack Trace:
Je ne comprends pas vraiment ce que cela signifie, mais c'est ce qui se passe lorsque je tente de filtrer une requête après un LongClick événement.
09-07 01: 46: 38,184 17027-17104/com.curtiswhite.www.sqlitedatabaseforephemeris I/OpenGLRenderer: Initialisé EGL, version 1.4 09-07 01: 47: 40,066 17027-17027/com.curtiswhite .www.sqlitedatabaseforephemeris E/SpannableStringBuilder: SPAN_EXCLUSIVE_EXCLUSIVE portées ne peut pas avoir une longueur nulle 09-07 01: 47: 40,066 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris E/SpannableStringBuilder: SPAN_EXCLUSIVE_EXCLUSIVE portées ne peut pas avoir une longueur nulle 09-07 01: 47: 45.036 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris E/SpannableStringBuilder: Les travées SPAN_EXCLUSIVE_EXCLUSIVE ne peuvent pas avoir une longueur nulle 09-07 01: 47: 45.036 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris E/S pannableStringBuilder: Les travées SPAN_EXCLUSIVE_EXCLUSIVE ne peuvent pas avoir une longueur nulle 09-07 01: 47: 45.991 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: beginBatchEdit sur inactif InputConnection 09-07 01: 47: 45.991 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: getSelectedText sur inactive InputConnection 09-07 01: 47: 46.003 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: endBatchEdit sur inactif InputConnection 09-07 01: 47: 46.003 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: getTextBeforeCursor sur inactif InputConnection 09-07 01:47 : 46.015 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: getTextAfterCursor sur inactif InputConnection 09-07 01: 47: 46.022 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: beginBatchEdit sur inactive InputC onnection 09-07 01: 47: 46.023 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: getSelectedText sur inactif InputConnection 09-07 01: 47: 46.023 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: endBatchEdit sur inactive InputConnection 09-07 01: 47: 46.023 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: getTextBeforeCursor sur inactif InputConnection 09-07 01: 47: 46.024 17027-17027/com. curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: getTextAfterCursor sur InputConnection inactive 09-07 01: 47: 46,027 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: beginBatchEdit sur InputConnection inactive 09-07 01: 47: 46,027 17027-17027/com.curtiswhi te.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: getSelectedText sur inactif InputConnection 09-07 01: 47: 46.027 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: endBatchEdit sur inactif InputConnection 09-07 01: 47: 46.028 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: getTextBeforeCursor sur InputConnection inactive 09-07 01: 47: 46,030 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: getTextAfterCursor sur InputConnection inactif 09- 07 01: 47: 46.062 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: beginBatchEdit sur inactif InputConnection 09-07 01: 47: 46.062 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: getSelectedText sur inactivé e InputConnection 09-07 01: 47: 46.062 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: endBatchEdit sur inactif InputConnection 09-07 01: 47: 46.063 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: getTextBeforeCursor sur InputConnection inactive 09-07 01: 47: 46,063 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: getTextAfterCursor sur InputConnection inactif
vous êtes dieu amzaing .... Merci pour le partage –