0

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

Répondre

1

Je résolu la question.

Il s'avère que le problème a été causé lors du gonflement du nouveau menu onLongClick. Cela a provoqué le SearchView de dégonfler (comme prévu), mais en appuyant sur en arrière (OnBackPressed est appelé), le menu d'origine se gonflerait, mais le SearchView qui a été placé là était un nouveau qui n'avait pas été instancié.

Pour corriger cela, j'ai simplement appelé OnCreateMenuOptions (toolbar.getMenu()); dans la méthode onBackPressed. Cela réinstancie le SearchView afin qu'il fonctionne à nouveau après le gonflement du menu.

+0

vous êtes dieu amzaing .... Merci pour le partage –