当前位置: 首页 > 知识库问答 >
问题:

如何让视图模型观察者最初不观察?

壤驷麒
2023-03-14

我在工具栏上有一个搜索视图图标,通过创建选项菜单(菜单菜单)。单击该图标将创建一个 EditText 行,供用户输入搜索输入。我有一个文本观察器()附加到编辑文本行,以便当文本添加到该行时(在文本更改可编辑之后),搜索查询方法通过搜索房间数据库的视图模型运行。

我的问题是,观察者甚至在用户输入任何查询之前就开始创建了。使用Toasts,我能够在用户按下SearchView图标时以及用户输入任何搜索查询之前,确认观察者正在运行一个空白查询“%%”。即使在afterTextChanged()中设置了观察者,也会发生这种情况。如何让ViewModel观察者仅在用户输入文本后触发?

Activity
...
@Override
public boolean onCreateOptionsMenu(Menu menu) {

getMenuInflater().inflate(R.menu.mainactiv_menu, menu);
searchItem = menu.findItem(R.id.action_search);
menu.findItem(R.id.action_search).setVisible(false);
if (cardsAdapter != null && cardsAdapter.getItemCount() > 0) {
    menu.findItem(R.id.action_search).setVisible(true);
}
SearchManager searchManager = (SearchManager) MainActivity.this.getSystemService(Context.SEARCH_SERVICE);
if (searchItem != null) {
    mSearchView = (SearchView) searchItem.getActionView();
    if (mSearchView != null) {
        mSearchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
        EditText mSearchEditText = mSearchView.findViewById(androidx.appcompat.R.id.search_src_text);
        mSearchEditText.setInputType(android.text.InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
        mSearchEditText.addTextChangedListener(new TextWatcher() {

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
               // not needed
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                // not needed
            }

            @Override
            public void afterTextChanged(Editable s) {

                String queryText = "%" + s.toString() + "%";

                mQuickcardViewModel.searchQuery(queryText).observe(MainActivity.this, searchCards -> {

                    searchList = searchCards;

                    if (!mSearchView.isIconified() && searchList.size() > 0) {
                        // do something
                    } 

                    ...     

共有1个答案

潘安平
2023-03-14

如何让ViewModel观察者在用户输入文本后才触发?

在观察之前,使用< code>if语句查看字符串是否为空:

@Override
public void afterTextChanged(Editable s) {
     if (s.toString().length() > 0) {
         // the rest of your code goes here, preferably with some modifications
     }
}

我建议的其他变化包括:

>

  • 添加一些防抖措施。给定您的搜索表达式,您似乎正在访问search chQuery()中的数据库。如果用户快速连续键入10个字符,您将进行10次查询,这将降低性能。“去抖”表示“仅在用户暂停一段时间后进行查询”,例如500毫秒,没有任何进一步的输入。

    添加智能以在需要时取消未完成的查询。假设用户键入了一点,然后反跳周期过去了。因此,您可以触发查询。由于您的(假定的)LIKE 表达式,您的查询将执行“表扫描”,检查表的每一行。这可能会很慢,并且用户可能会在第一个查询完成之前开始键入更多内容。您不再需要该查询,因为它的结果是错误的(它适用于以前的搜索表达式,而不是当前搜索表达式)。因此,您需要一种方法来取消该工作。

    处理配置更改。你可能会争辩说你正在使用视图模型实时数据,它们应该处理这个问题......它确实如此,但前提是您正确使用它们。在您的情况下,您似乎在观察它之后丢弃了该LiveData,并且以此类推,配置更改,您将无法在位置上重新观察它。这就是为什么很多样本都集中在将“请做后台工作”与“请给我后台工作的结果”脱钩的原因。您仍然可以使用调用的搜索查询()方法,但它将返回 void。结果将通过视图模型保存的一些实时数据进行管道传输,您可以在 onCreate() 中观察到这些实时数据。这样,在配置更改后,您再次观察 LiveData,并获取该配置更改之前的数据。

    利用FTS。< code>LIKE比较慢。如果您经常这样做,可以考虑在SQLite中使用FTS3/FTS4进行全文搜索。如果您使用的是Room,那么在Room 2.2.0中对此有内置的支持。

  •  类似资料:
    • 是否有一种设计模式可以形成一个“复合”观察者/可观察者? 我的意思是我有一个可观察的,它在某个变化时通知它的监听器。 每个监听器也是一个可观察的,并通知它自己的监听器(在某个动作上,它做了哪个动作是由第一个可观察的通知触发的)。 这种观察者/可观察的“链接”作为设计是可以的,还是有一个标准的模式?

    • 主要内容:介绍,实现,Subject.java,Observer.java,BinaryObserver.java,OctalObserver.java,HexaObserver.java,ObserverPatternDemo.java当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。 介绍 意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知

    • 当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。 介绍 意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。 主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。 何时使用:一个对象(目标对象)

    • 观察者模式是软件设计模式的一种。在此种模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实时事件处理系统。 定义一个目标构造函数,并实现绑定、解绑和触发等方法: function Subject() { this.events = {}; this.count = 0; }​ Subj

    • 问题 当一个事件发生时你不得不向一些对象发布公告。 解决方案 使用观察者模式(Observer Pattern)。 class PostOffice constructor: () -> @subscribers = [] notifyNewItemReleased: (item) -> subscriber.callback(item) for s

    • 简介 观察者模式(有时又被称为发布/订阅模式)是软件设计模式的一种。在此种模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实时事件处理系统。 抽象目标类别 此抽象类别提供一个界面让观察者进行添附与解附作业。此类别内有个不公开的观察者串炼,并透过下列函式(方法)进行作业 添附(Attach):新增观察