SearchView+RecyclerView+GreenDao的搜索功能实现(2)

简单的界面效果如下

SearchView+RecyclerView+GreenDao的搜索功能实现(2)_第1张图片 SearchView+RecyclerView+GreenDao的搜索功能实现(2)_第2张图片

SearchView+RecyclerView+GreenDao的搜索功能实现(2)_第3张图片

布局如下,通过一个RecyclerView控制显示三种情况的显示

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                tools:context=".MainActivity">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/material_primary"
        android:theme="@style/ToolBarStyle"
        app:popupTheme="@style/Theme.AppCompat.Light">
    </android.support.v7.widget.Toolbar>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/toolbar"
        android:background="@color/material_icons"
        android:scrollbars="none"/>

    <TextView
        android:id="@+id/tv_tip"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="25sp"
        android:textColor="@color/material_red_a700"
        android:text="Open The SearchView"
        android:layout_centerInParent="true"/>

</RelativeLayout>

①界面初始化,简单设置下Toolbar,RecyclerView ,
mHistoryOrAllSearchList用于存放历史或联想词;mHotSearchList用于存放热词
SharedPreUtil.readString(Constant.OPENTIME).isEmpty()用来模拟版本变化更新数据库
更新数据库会将上版本的热词和联想词删除,涉及到大数据量,所以开线程操作mKeywordsTableDao.getSession().runInTx

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar);
        if (mToolbar == null) {
            return;
        }
        mToolbar.setTitle(R.string.app_name);
        setSupportActionBar(mToolbar);

        RecyclerView mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        StaggeredGridLayoutManager mManager = new StaggeredGridLayoutManager(2, 
                                                StaggeredGridLayoutManager.VERTICAL);
        mRecyclerView.setLayoutManager(mManager);
        mRecyclerView.addItemDecoration(new SpacesItemDecoration(5));

        mAdapter = new SearchAdapter(this);
        mAdapter.setItemClickLitener(this);

        mRecyclerView.setAdapter(mAdapter);

        mHistoryOrAssociativeSearchList = new ArrayList<>();
        mHotSearchList = new ArrayList<>();

        mKeywordsTableDao = getSearchKeywordsTableDao(mKeywordsTableDao);

        if (SharedPreUtil.readString(Constant.OPENTIME).isEmpty()) {
            // 词库版本有更新才去更新数据库的热词和练习词
            final List<SearchKeywords> keywordses = new ArrayList<>();

            // 热词
            keywordses.add(new SearchKeywords("women", 12, -1, Constant.SEARCH_KEYWORDS_HOT));
            keywordses.add(new SearchKeywords("men", 10, -1, Constant.SEARCH_KEYWORDS_HOT));
            keywordses.add(new SearchKeywords("beauty", 16, -1, Constant.SEARCH_KEYWORDS_HOT));
            keywordses.add(new SearchKeywords("makeup", 2, -1, Constant.SEARCH_KEYWORDS_HOT));
            keywordses.add(new SearchKeywords("clothes", 6, -1, Constant.SEARCH_KEYWORDS_HOT));

            // 联想词
            keywordses.add(new SearchKeywords("women", 12, -1, 
                            Constant.SEARCH_KEYWORDS_ASSOCIATIVE));
            keywordses.add(new SearchKeywords("men", 10, -1, 
                            Constant.SEARCH_KEYWORDS_ASSOCIATIVE));
            keywordses.add(new SearchKeywords("beauty", 16, -1, 
                            Constant.SEARCH_KEYWORDS_ASSOCIATIVE));
            keywordses.add(new SearchKeywords("makeup", 2, -1,   
                            Constant.SEARCH_KEYWORDS_ASSOCIATIVE));
            keywordses.add(new SearchKeywords("clothes", 6, -1, 
                            Constant.SEARCH_KEYWORDS_ASSOCIATIVE));
            keywordses.add(new SearchKeywords("cute", 26, -1, 
                            Constant.SEARCH_KEYWORDS_ASSOCIATIVE));
            keywordses.add(new SearchKeywords("watch", 32, -1, 
                            Constant.SEARCH_KEYWORDS_ASSOCIATIVE));
            keywordses.add(new SearchKeywords("sexy", 16, -1, 
                            Constant.SEARCH_KEYWORDS_ASSOCIATIVE));

            mKeywordsTableDao.getSession().runInTx(new Runnable() {
                @Override
                public void run() {
                    // 避免数据太多阻塞主线程
                    // 清除旧版本的热词和联想词
                    clearTopAndAssociativeSearchKeyWords();
                    insertSearchKeywordsToDb(keywordses);
                }
            });

            SharedPreUtil.writeString(Constant.OPENTIME, System.currentTimeMillis() + "");
        }

    }

②RecyclerView适配器的设计

会有三种视图模式,暴露方法获取当前模式和设置当前模式

    // 历史和热词模式
    public static final int MODE_KEYWORDS_REVIEW = 0;
    // 搜索结果模式
    public static final int MODE_RESULT = 1;
    // 联想匹配模式
    public static final int MODE_KEYWORDS_MATCH = 2;

    public int getCurrentMode() {
        return mCurrentMode;
    }

    public void setCurrentMode(int currentMode) {
        this.mCurrentMode = currentMode;
    }

    private int mCurrentMode;

填充数据有两个成员变量

    /** * 搜索热词 */
    private List<String> mHotSearchList;

    public List<String> getHotSearchList() {
        return mHotSearchList;
    }

    public void setHotSearchList(List<String> allSearchList) {
        this.mHotSearchList = allSearchList;
    }

    /** * 搜索历史,或者是匹配的单词 */
    private List<String> mHistoryOrAssociativeSearchList;

    public List<String> getHistoryOrAssociativeSearchList() {
        return mHistoryOrAssociativeSearchList;
    }

    public void setHistoryOrAssociativeSearchList(List<String> historyOrAssociativeSearchList) {
        this.mHistoryOrAssociativeSearchList = historyOrAssociativeSearchList;
    }

有四种View类型:
①VIEW_TYPE_TIP ,标题,在显示历史和热搜的时候为标识类型;显示搜索结果的时候标识搜索结果的搜索单词
②VIEW_TYPE_KEYWORD ,搜索单词
③VIEW_TYPE_RESULT ,搜索结果
④VIEW_TYPE_DELETE_HISTORY,一键清空的布局

    private final int VIEW_TYPE_TIP = 0;
    private final int VIEW_TYPE_KEYWORD = 1;
    private final int VIEW_TYPE_RESULT = 2;
    private final int VIEW_TYPE_DELETE_HISTORY = 3;

    @Override
    public SearchAdapter.RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        RecyclerViewHolder viewHolder;
        switch (viewType) {
            case VIEW_TYPE_TIP:
                viewHolder = new RecyclerViewHolder
                (LayoutInflater.from(mContext).inflate(R.layout.item_search_head, parent, false));
                return viewHolder;
            case VIEW_TYPE_KEYWORD:
                View view LayoutInflater.from(mContext).inflate(R.layout.item_search, 
                parent, false);
                viewHolder = new RecyclerViewHolder(view);
                view.findViewById(R.id.iv_delete).setOnClickListener(this);
                view.findViewById(R.id.ll_search).setOnClickListener(this);
                return viewHolder;
            case VIEW_TYPE_RESULT:
                viewHolder = new RecyclerViewHolder
               (LayoutInflater.from(mContext).inflate(R.layout.item_search_result, parent, false));
                return viewHolder;
            case VIEW_TYPE_DELETE_HISTORY:
                View view1 = 
                LayoutInflater.from(mContext).inflate(R.layout.item_search_delete_history, parent, 
                false);
                viewHolder = new RecyclerViewHolder(view1);
                view1.findViewById(R.id.tv_clear_history).setOnClickListener(this);
                return viewHolder;
        }
        return null;
    }

    @Override
    public void onBindViewHolder(SearchAdapter.RecyclerViewHolder holder, int position) {
        switch (getItemViewType(position)) {
            case VIEW_TYPE_TIP:
                StaggeredGridLayoutManager.LayoutParams lp = 
                (StaggeredGridLayoutManager.LayoutParams) holder.mHeadLayout.getLayoutParams();
                lp.setFullSpan(true);
                if (mCurrentMode != MODE_RESULT) {
                // 历史和热词模式,位置不为0,说明同时存在历史和热搜,标配自然是“Hot”,如果等于0,
                    holder.mTitleText.setText(position != 0 ? "Hot" : mHistoryExist ? 
                    "History" : "Hot");
                } else {
                // 结果模式,搜索单词
                    holder.mTitleText.setText("word: " + mSearchWord);
                }
                break;

            case VIEW_TYPE_DELETE_HISTORY:
                // 不用做任何事,只是一个点击事件清空历史
                StaggeredGridLayoutManager.LayoutParams lp3 = 
                (StaggeredGridLayoutManager.LayoutParams) ((ViewGroup) 
                holder.mClearHistoryText.getParent()).getLayoutParams();
                lp3.setFullSpan(true);
                break;

            case VIEW_TYPE_KEYWORD:

                StaggeredGridLayoutManager.LayoutParams lp1 = 
                (StaggeredGridLayoutManager.LayoutParams) ((ViewGroup) 
                holder.mSearchKeyWordText.getParent()).getLayoutParams();
                lp1.setFullSpan(true);

                if (mCurrentMode == MODE_KEYWORDS_MATCH) {
                // 联想匹配模式
                    if (mHistoryExist) {
                        holder.mDeleteImg.setVisibility(View.GONE);
        holder.mSearchKeyWordText.setText(mHistoryOrAssociativeSearchList.get(position));
                        holder.mSearchLayout.setTag(position);
                    }
                } else if (mCurrentMode == MODE_KEYWORDS_REVIEW) {
                // 历史和热搜模式
                    if (mHistoryExist) {
                    // 存在历史数据
                        if (position < mHistoryOrAssociativeSearchList.size() + 1) { 
                        // 删除按钮设置为可见,历史可以删除 
                        holder.mSearchKeyWordText
                        .setText(mHistoryOrAssociativeSearchList.get(position - 1));
                            holder.mDeleteImg.setVisibility(View.VISIBLE);
                            holder.mDeleteImg.setTag(position - 1);
                            holder.mSearchLayout.setTag(position - 1);
                        } else {
                        // 设置热搜数据
// DebugLog.e("position=" + position);
                            holder.mDeleteImg.setVisibility(View.GONE);
                            holder.mSearchKeyWordText.setText(mHotSearchList.get(position - 3 - 
                            mHistoryOrAssociativeSearchList.size()));
                            holder.mSearchLayout.setTag(position - 3);
                        }
                    } else if (mHotExist) {
                    // 只存在热搜数据
                        holder.mDeleteImg.setVisibility(View.GONE);
                        holder.mSearchKeyWordText.setText(mHotSearchList.get(position - 1));
                        holder.mSearchLayout.setTag(position - 1);
                    }
                }
                break;
            case VIEW_TYPE_RESULT:
            // 搜索结果
                StaggeredGridLayoutManager.LayoutParams lp2 = 
                (StaggeredGridLayoutManager.LayoutParams) ((ViewGroup) 
                holder.mResultText.getParent()).getLayoutParams();
                lp2.setFullSpan(true);
                holder.mResultText.setText("The search word is " + mSearchWord);
                break;

        }
    }

    @Override
    public int getItemViewType(int position) {
        if (mCurrentMode == MODE_KEYWORDS_REVIEW) {
            int hotTitlePosition = 0;
            if (mHistoryExist && mHotExist) {
                // 同时存在的时候才有第二个标题
                hotTitlePosition = mHistoryOrAssociativeSearchList.size() + 1 + 1;
            }
            if (mHistoryExist && position == mHistoryOrAssociativeSearchList.size() + 1) {
                // 有历史记录存在,历史纪录后面是一个一键情空历史按钮
                return VIEW_TYPE_DELETE_HISTORY;
            }
            return position == 0 || position == hotTitlePosition ? VIEW_TYPE_TIP : 
            VIEW_TYPE_KEYWORD;
        } else if (mCurrentMode == MODE_KEYWORDS_MATCH) {
            return VIEW_TYPE_KEYWORD;
        } else if (mCurrentMode == MODE_RESULT) {
            return position == 0 ? VIEW_TYPE_TIP : VIEW_TYPE_RESULT;
        }
        return -1;
    }

    boolean mHistoryExist;
    boolean mHotExist;

    @Override
    public int getItemCount() {
        int itemCount = 0;
        if (mCurrentMode == MODE_KEYWORDS_REVIEW) {
            mHistoryExist = mHistoryOrAssociativeSearchList != null && 
            mHistoryOrAssociativeSearchList.size() > 0;
            mHotExist = mHotSearchList != null && mHotSearchList.size() > 0;
            if (mHistoryExist) {
                // 存在历史,加个历史的标题
                itemCount += mHistoryOrAssociativeSearchList.size() + 1;
                // 加个一键清空历史的按钮
                itemCount += 1;
                if (mHotExist) {
                    // 存在热搜,加个热搜的标题
                    itemCount += mHotSearchList.size() + 1;
                }
            } else {
                // 不存在历史
                if (mHotExist) {
                    // 存在热搜,加个热搜的标题
                    itemCount += mHotSearchList.size() + 1;
                }
            }
        } else if (mCurrentMode == MODE_KEYWORDS_MATCH) {
            mHistoryExist = mHistoryOrAssociativeSearchList != null && 
            mHistoryOrAssociativeSearchList.size() > 0;
            if (mHistoryExist) {
                itemCount += mHistoryOrAssociativeSearchList.size();
            }
        } else if (mCurrentMode == MODE_RESULT) {
            // 结果是标题加text显示搜索词语
            return itemCount += 2;
        }

        return itemCount;
    }

菜单的设置

    private MenuItem mSearchItem;

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);

        mSearchItem = menu.findItem(R.id.action_search);

        final SearchView searchView = (SearchView) MenuItemCompat.getActionView(mSearchItem);

        final SearchView.SearchAutoComplete searchEditText = (SearchView.SearchAutoComplete) 
        searchView.findViewById(R.id.search_src_text);

        searchView.setQueryHint("Search");

        // 将搜索按钮放到搜索输入框的外边
        searchView.setIconifiedByDefault(false);

        // 设置输入框底部的横线的颜色
        View searchPlate = searchView.findViewById(android.support.v7.appcompat.R.id.search_plate);
        searchPlate.setBackgroundResource(R.mipmap.ic_searchview_plate);
      searchPlate.getBackground().setColorFilter(getResources().getColor(R.color.material_a
      ccent), PorterDuff.Mode.SRC_ATOP);

        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                // 提交查询条件
                DebugLog.e("提交查询:" + query);
                submitKeywords(query);
                searchEditText.setText("");
                return true;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                // 这里做搜索联想
                if (mAdapter.getCurrentMode() == SearchAdapter.MODE_RESULT) {
                    DebugLog.e("搜索结果模式,不做处理");
                    return true;
                }
                if (newText.isEmpty()) {
                    DebugLog.e("搜索为空,显示历史和热词");
                    showHistoryAndHotKeywords();
                } else {
                    DebugLog.e("搜索词不为空,显示匹配");
                    mHotSearchList.clear();
                    mHistoryOrAssociativeSearchList.clear();
                    insertMatchKeywordsToRecycleView(mHistoryOrAssociativeSearchList, newText);
                    mAdapter.setCurrentMode(SearchAdapter.MODE_KEYWORDS_MATCH);
                    mAdapter.setHistoryOrAssociativeSearchList(mHistoryOrAssociativeSearchList);
                    mAdapter.notifyDataSetChanged();
                }

                return true;
            }
        });

        return true;
    }

点击事件的处理

    /** * 提交结果 * * @param query */
    private void submitKeywords(String query) {
        mAdapter.setCurrentMode(SearchAdapter.MODE_RESULT);
        final SearchKeywords keywords = new SearchKeywords(query, -1, System.currentTimeMillis(), 
        Constant.SEARCH_KEYWORDS_HISTORY);
        insertHistorySearchKeywordsToDb(keywords);
        hideKeybord(MainActivity.this, MainActivity.this.getCurrentFocus());
        mAdapter.setSearchWord(query);
        mAdapter.notifyDataSetChanged();
        MenuItemCompat.collapseActionView(mSearchItem);
    }

    /** * 显示历史和热词 */
    private void showHistoryAndHotKeywords() {
        mAdapter.setCurrentMode(SearchAdapter.MODE_KEYWORDS_REVIEW);
        mHotSearchList.clear();
        mHistoryOrAssociativeSearchList.clear();
        insertKeywordsToRecyclerView(mHistoryOrAssociativeSearchList, 
        Constant.SEARCH_KEYWORDS_HISTORY);
        insertKeywordsToRecyclerView(mHotSearchList, Constant.SEARCH_KEYWORDS_HOT);
        mAdapter.setHistoryOrAssociativeSearchList(mHistoryOrAssociativeSearchList);
        mAdapter.setHotSearchList(mHotSearchList);
        mAdapter.notifyDataSetChanged();
    }

    @Override
    public void onItemClick(View view, int position) {
        switch (view.getId()) {
            case R.id.iv_delete:
                hideKeybord(MainActivity.this, MainActivity.this.getCurrentFocus());
                DebugLog.e("删除历史: " + mHistoryOrAssociativeSearchList.get(position));
                clearSearchKeyWords(mHistoryOrAssociativeSearchList.get(position));
                mHistoryOrAssociativeSearchList.remove(position);
                mAdapter.notifyDataSetChanged();
                break;
            case R.id.ll_search:
                boolean historyExist = mHistoryOrAssociativeSearchList != null && 
                mHistoryOrAssociativeSearchList.size() > 0;
                boolean hotExist = mHotSearchList != null && mHotSearchList.size() > 0;
                String keyword = null;
                if (historyExist) {
                    if (position >= mHistoryOrAssociativeSearchList.size()) {
                        // 点击的是热搜
                        keyword = mHotSearchList.get(position - 
                        mHistoryOrAssociativeSearchList.size());
                        DebugLog.e("点击的是热搜: " + keyword);
                    } else {
                        keyword = mHistoryOrAssociativeSearchList.get(position);
                        if (mAdapter.getCurrentMode() == SearchAdapter.MODE_KEYWORDS_MATCH) {
                            DebugLog.e("点击的是联想的匹配: " + keyword);
                        } else if (mAdapter.getCurrentMode() == SearchAdapter.MODE_KEYWORDS_REVIEW) {
                            DebugLog.e("点击的是历史: " + keyword);
                        }
                    }
                } else if (hotExist) {
                    keyword = mHotSearchList.get(position);
                    DebugLog.e("点击的是热搜: " + keyword);
                }
                if (keyword != null) {
                    submitKeywords(keyword);
                    MenuItemCompat.collapseActionView(mSearchItem);
                }
                break;
            case R.id.tv_clear_history:
                DebugLog.e("点击了一键清空历史");
                clearHisotySearchKeyWords();
                mHistoryOrAssociativeSearchList.clear();
                mAdapter.setCurrentMode(SearchAdapter.MODE_KEYWORDS_REVIEW);
                mAdapter.notifyDataSetChanged();
                break;
        }
    }

总结:

可能说得不是很清楚,附上demo,跑一下,看下源码估计就差不多了>_<

SearchView+GreenDao搜索功能实现

你可能感兴趣的:(android,搜索)