SearchView在LongClick操作

时间:2016-09-07 04:21:30

标签: java android searchview onlongclicklistener onitemlongclicklistener

在我的应用中,SearchView中有Toolbar

当用户点击搜索图标时,SearchView会展开,用户就会开始输入。搜索查询按标题过滤RecyclerView列表。一切正常。

但是,当我对其中一个RecyclerView项执行OnLongClick操作时,过滤器功能会停止工作。

我有一个OnClickListener和OnLongClickListener都附加到每个RecyclerView持有者,但它只是阻止SearchView过滤的 OnLongClick 操作。我不明白为什么。我尝试重新验证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>

我相信所有影响它的代码,但如果还有其他任何需要让我知道的话。

这里是Stack Trace:

我真的不明白这意味着什么,但是当我尝试在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:getSelectedText在非活动的InputConnection上       09-07 01:47:46.0​​03 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:非活动InputConnection上的endBatchEdit       09-07 01:47:46.0​​03 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:getTextBeforeCursor on inactive InputConnection       09-07 01:47:46.0​​15 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:getTextAfterCursor on inactive InputConnection       09-07 01:47:46.0​​22 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:非活动InputConnection上的beginBatchEdit       09-07 01:47:46.0​​23 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:getSelectedText在非活动的InputConnection上       09-07 01:47:46.0​​23 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:非活动InputConnection上的endBatchEdit       09-07 01:47:46.0​​23 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:getTextBeforeCursor on inactive InputConnection       09-07 01:47:46.0​​24 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:getTextAfterCursor on inactive InputConnection       09-07 01:47:46.0​​27 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:非活动InputConnection上的beginBatchEdit       09-07 01:47:46.0​​27 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:getSelectedText在非活动的InputConnection上       09-07 01:47:46.0​​27 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:非活动InputConnection上的endBatchEdit       09-07 01:47:46.0​​28 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:getTextBeforeCursor on inactive InputConnection       09-07 01:47:46.0​​30 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:getTextAfterCursor on inactive InputConnection       09-07 01:47:46.0​​62 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:非活动InputConnection上的beginBatchEdit       09-07 01:47:46.0​​62 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:getSelectedText在非活动的InputConnection上       09-07 01:47:46.0​​62 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:非活动InputConnection上的endBatchEdit       09-07 01:47:46.0​​63 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:getTextBeforeCursor on inactive InputConnection       09-07 01:47:46.0​​63 17027-17027 / com.curtiswhite.www.sqlitedatabaseforephemeris W / IInputConnectionWrapper:getTextAfterCursor on inactive InputConnection

1 个答案:

答案 0 :(得分:1)

我解决了这个问题。

事实证明,问题是在LongLot上点击新菜单时引起的。这导致SearchView放气(如预期的那样),但在按下后(OnBackPressed被调用),原始菜单会膨胀,但放在那里的SearchView是一个新的,但没有实例

为了纠正这个问题,我简单地调用了OnCreateMenuOptions(toolbar.getMenu());在onBackPressed方法中。这会重新验证SearchView,以便在菜单膨胀后再次运行。