美文网首页安卓开发
RecyclerView + toolbar + searchv

RecyclerView + toolbar + searchv

作者: lisx_ | 来源:发表于2018-05-10 15:45 被阅读315次

    RecyclerView + toolbar + searchview的实现搜索关联分为以下几步:

    一,添加toolbar的布局:

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.design.widget.AppBarLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/xxx"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:elevation="0dp">
    
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="@color/xxx"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:layout_scrollFlags="scroll|enterAlways"
            app:navigationIcon="@drawable/xxx" />
    </android.support.design.widget.AppBarLayout>
    

    二,然后在menu文件中添加toolbar的searchview菜单,默认为图标,可以实现点击展开

    <?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/xxx"
            android:icon="@drawable/icon_search"
            android:iconifiedByDefault="true"
            android:imeOptions="actionSearch"
            android:title="@string/xxx"
            app:actionViewClass="android.support.v7.widget.SearchView"
            app:showAsAction="collapseActionView|ifRoom" />
    </menu>
    

    这里需要把showAsAction设置为"collapseAction|ifRoom"
    showAsAction属性共有五个值:ifRoom、never、always、withText、collapseActionView,可以混合使用。具体介绍如下:

    ifRoom
    会显示在Item中,但是如果已经有4个或者4个以上的Item时会隐藏在溢出列表中。当然个数并不仅仅局限于4个,依据屏幕的宽窄而定

    never
    永远不会显示。只会在溢出列表中显示,而且只显示标题,所以在定义item的时候,最好把标题都带上。

    always
    无论是否溢出,总会显示。

    withText
    withText值示意Action bar要显示文本标题。
    Action bar会尽可能的显示这个标题,但是,
    如果图标有效并且受到Action bar空间的限制,文本标题有可能显示不全。

    collapseActionView
    声明了这个操作视窗应该被折叠到一个按钮中,当用户选择这个按钮时,这个操作视窗展开。否则,这个操作视窗在默认的情况下是可见的,并且即便在用于不适用的时候,也要占据操作栏的有效空间。一般要配合ifRoom一起使用才会有效果。

    imeOptions属性分别是:

    actionDone 完成 对应 EditorInfo.IME_ACTION_DONE
    actionGo 前进 对应 EditorInfo.IME_ACTION_GO
    actionNext 下一项 对应 EditorInfo.IME_ACTION_NEXT
    actionNone 无动作 对应 EditorInfo.IME_ACTION_NONE
    actionPrevious 上一项 对应 EditorInfo.IME_ACTION_PREVIOUS
    actionSearch 搜索 对应 EditorInfo.IME_ACTION_SEARCH
    actionUnspecified 未指定 对应 EditorInfo.IME_ACTION_UNSPECIFIED
    actionSend 发送 对应 EditorInfo.IME_ACTION_SEND

    actionViewClass设置为系统或者v7库的searchview组件

    三,Activity中的操作

    使用线程池处理

        private ScheduledExecutorService mScheduledExecutor = Executors.newScheduledThreadPool(10);
        
        public ScheduledFuture<?> schedule(Runnable command, long delayTimeMills) {
            return mScheduledExecutor.schedule(command, delayTimeMills, TimeUnit.MILLISECONDS);
        }
    

    绑定Toolbar,加载RecyclerView

            setSupportActionBar(mToolbar);
            mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    finish();
                }
            });
    
            // 设置布局管理器
            LinearLayoutManager layoutManager = new LinearLayoutManager(this);
            layoutManager.setOrientation(OrientationHelper.VERTICAL);
            mRecyclerView.setLayoutManager(layoutManager);
            mRecyclerView.addItemDecoration(new DividerItemDecoration(
                    this, DividerItemDecoration.VERTICAL));
            
            //加载数据  
            mSchedualDatas = xxxDBHelper.getxxxByType(xxx.xxx);
            mAdapter = new xxx(this, mDatas);
            mRecyclerView.setAdapter(mAdapter);
        }
    

    创建菜单,使用SearchView

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            menu.clear();
            getMenuInflater().inflate(R.menu.xxx, menu);
            MenuItem menuItem = menu.findItem(R.id.xxx);
            mSearchView = (SearchView) MenuItemCompat.getActionView(menuItem);//加载searchview
            initSearchView();
            return true;
        }
    

    为SearchView添加监听事件

        public void initSearchView() {
            mSearchView.setOnCloseListener(new SearchView.OnCloseListener() {
                @Override
                public boolean onClose() {
                    return true;
                }
            });
            mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
    
                @Override
                public boolean onQueryTextSubmit(String query) {
                    return false;
                }
    
                @Override
                public boolean onQueryTextChange(String newText) {
                    if (TextUtils.isEmpty(newText)) {
                        return false;
                    }
                    showSearchTip(newText);
                    return true;
                }
            });
        }
        
        public void showSearchTip(String newText) {
            schedule(new SearchTipThread(newText), 100);
        }
    

    创建线程处理耗时的查询操作

        class SearchTipThread implements Runnable {
            String newText;
    
            public SearchTipThread(String newText) {
                this.newText = newText;
            }
    
            public void run() {
                if (newText.equals(mCurrentSearchTip)) {
                    return;
                }
                mCurrentSearchTip = newText;
                mSchedualDatas = xxxDBHelper.getxxxByWord(newText, xxx);
                mUpdateHandler.sendMessage(mUpdateHandler.obtainMessage(MSG_UPDATE));
            }
        }
    

    创建Handler,在主线程更新UI. 这里需要Adapter的数据项产生变化后,调用notifyDataSetChanged才能更新RecyclerView.

        private class UpdateHandler extends Handler {
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case MSG_UPDATE:
                        mAdapter.setDatas(mDatas);
                        mAdapter.notifyDataSetChanged();
                        break;
                }
            }
        }
    }
    
    

    这样一个搜索页就做出来了.

    四, Rxjava的改造

    上面的例子里,线程池 handler什么的,逻辑太分散, 不妨用之前学得Rxjava改造一下:

        protected void showSearchTip(String newText) {
            Observable.just(newText)
                    .subscribeOn(Schedulers.io())
                    .map(new Function<String, List<xxx>>() {
                        @Override
                        public List<xxx> apply(String str) throws Exception {
                            if (!TextUtils.isEmpty(str) && str.equals(mCurrentSearchTip)) {
                                return null;
                            }
                            List<xxx> datas;
                            if (TextUtils.isEmpty(str)) {
                                datas = DBHelper.getxxxByType(xxx);
                            } else {
                                datas = DBHelper.gexxxByWord(str, xxx);
                            }
                            mCurrentSearchTip = str;
                            return datas;
                        }
                    })
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<List<xxx>>() {
                        @Override
                        public void accept(List<xxx> xxx) throws Exception {
                            getV().updateAdapter(xxx);
                        }
                    });
        }
    
    

    这下好看多了 : )

    相关文章

      网友评论

        本文标题:RecyclerView + toolbar + searchv

        本文链接:https://www.haomeiwen.com/subject/zpazrftx.html