0

В моем приложении у меня есть SearchView в Toolbar.SearchView останавливает фильтрацию после действия LongClick

Когда пользователь нажимает значок поиска, SearchView расширяется и пользователь начинает печатать. Поисковый запрос фильтрует список RecyclerView по названию. Все это прекрасно работает.

Однако функция фильтра перестает работать, когда я выполняю действие OnLongClick на одном из элементов RecyclerView.

У меня есть одновременно OnClickListener и OnLongClickListener прилагается к каждому держателю RecyclerView, но это только 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 Е/SpannableStringBuilder: SPAN_EXCLUSIVE_EXCLUSIVE пролеты не может иметь нулевую длину 09-07 01: 47: 40,066 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris Е/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/S pannableStringBuilder: SPAN_EXCLUSIVE_EXCLUSIVE промежутки не могут иметь нулевую длину 09-07 01: 47: 45.991 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: beginBatchEdit неактивного InputConnection 09-07 01: 47: 45,991 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: getSelectedText на неактивный InputConnection 09-07 01: 47: 46,003 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: endBatchEdit неактивного InputConnection 09-07 01: 47: 46.003 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris Вт/IInputConnectionWrapper: getTextBeforeCursor на неактивном InputConnection 09-07 01:47 : 46.015 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: getTextAfterCursor on inactive InputConnection 09-07 01: 47: 46.022 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: beginBatchEdit on inactive InputC onnection 09-07 01: 47: 46.023 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: getSelectedText on inactive InputConnection 09-07 01: 47: 46.023 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: endBatchEdit on inactive InputConnection 09-07 01: 47: 46.023 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: getTextBeforeCursor on inactive InputConnection 09-07 01: 47: 46.024 17027-17027/com. curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: getTextAfterCursor неактивного InputConnection 09-07 01: 47: 46,027 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris Вт/IInputConnectionWrapper: beginBatchEdit на неактивном InputConnection 09-07 01: 47: 46,027 17027-17027/com.curtiswhi te.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: getSelectedText on inactive InputConnection 09-07 01: 47: 46.027 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: endBatchEdit on inactive InputConnection 09-07 01: 47: 46.028 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: getTextBeforeCursor неактивного InputConnection 09-07 01: 47: 46.030 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris Вт/IInputConnectionWrapper: getTextAfterCursor на неактивном InputConnection 09- 07 01: 47: 46.062 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: beginBatchEdit on inactive InputConnection 09-07 01: 47: 46.062 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: getSelectedText по инактивации e InputConnection 09-07 01: 47: 46.062 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: endBatchEdit on inactive InputConnection 09-07 01: 47: 46.063 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris W/IInputConnectionWrapper: getTextBeforeCursor неактивного InputConnection 09-07 01: 47: 46,063 17027-17027/com.curtiswhite.www.sqlitedatabaseforephemeris Вт/IInputConnectionWrapper: getTextAfterCursor неактивного InputConnection

ответ

1

Я решил эту проблему.

Оказалось, что проблема возникла при раздувании нового меню onLongClick. Это вызвало отклонение SearchView (как и ожидалось), но при нажатии на него (OnBackPressed получает вызов) исходное меню будет раздуваться, но SearchView, который был помещен в него, был новым, который не был создан.

Чтобы исправить это, я просто вызвал OnCreateMenuOptions (toolbar.getMenu()); в методе onBackPressed. Это восстанавливает SearchView, поэтому он снова будет работать после раздувания меню.

+0

вы бог amzaing .... Спасибо за обмен –

Смежные вопросы