美文网首页安卓开发
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