【问题标题】:EditText lag when searching a list in a textWatcher在 textWatcher 中搜索列表时 EditText 滞后
【发布时间】:2018-05-19 12:19:14
【问题描述】:

这是我的TextWatcher

searchBox.addTextChangedListener(new TextWatcher() {

            @Override
            public void beforeTextChanged( CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(final CharSequence charSequence, int i, int i1, int i2) {
                ArrayList<ProductInformation> newList = new ArrayList<>();
                for (ProductInformation info : currentList)
                    if (info.getName().contains(charSequence))
                        newList.add(info);
                productListAdapter.setNewData(newList);

            }

            @Override
            public void afterTextChanged(Editable editable) {

            }
        });

将这个listener 添加到我的editText 后,打字时会出现延迟。 我猜问题是在列表中搜索(列表中有 40 到 60 个项目)。

我能做什么?

【问题讨论】:

  • 对项目使用 TreeMap 或 HashMap 而不是 ArrayList。
  • @Juan 有什么区别?
  • 要在ArrayList中查找,它有顺序一一检查,TreeMap使用二分查找,hashmap应该一步解决查找。 Hashmap 不完全是这样,但它就是这个想法。

标签: android android-edittext


【解决方案1】:

实时文本搜索对更好的性能有一些要求:

要求

  • 您不应该立即开始搜索,因为用户输入速度非常快,并且下一个结果会立即覆盖最后一个结果。多个搜索过程运行,但只显示最后一个结果会浪费性能。

  • 尽量使搜索异步,即使是网络请求或只是本地搜索,这样就不会损害 UI 并且可以轻松取消。

解决方案

在输入过程中使用TimerTimerTask 进行延迟和取消

private Timer mRequestDelayTimer;
private TimerTask mSearchTask;

@Override
public void onTextChanged(final CharSequence query, int i, int i1, int i2) {
    if (mRequestDelayTimer != null)
        mRequestDelayTimer.cancel();

    // If you do a async search, stop it here
    stopSearch();

    mRequestDelayTimer = new Timer();
    mSearchTask = new TimerTask() {
        @Override
        public void run() {
            startSearch(query);
        }
    };
    mRequestDelayTimer.schedule(mSearchTask, 500);
}

private synchronized void startSearch(String query) {
    // This is not run in UI thread. Use activity.runOnUiThread if you want to update the UI
    // Call an AsyncTask to do an async search or run a sync loop search here

    //ArrayList<ProductInformation> newList = new ArrayList<>();
    //for (ProductInformation info : currentList)
    //    if (info.getName().contains(charSequence))
    //        newList.add(info);
    //productListAdapter.setNewData(newList);
}

说明

如果输入的每个字符都在 500ms 内,则不会调用 startSearch,因为计时器一直在延迟。

如果用户休息时间超过 500 毫秒,startSearch 会从 UI 线程中调用。那么如果用户在搜索过程中开始输入,就会被取消。

如果您在ArrayAdapter 中进行搜索和更新结果,它有一个内置的Filter 进程,您可以通过覆盖getFilter 来自定义它。这个过滤器在后台自动运行,对输入的每个字符进行取消,非常方便。参考:Custom getFilter in custom ArrayAdapter in android

你的实际实现可能不同,但思路是一样的

【讨论】:

  • 感谢这个不错的解决方案,我认为用户休息的最佳时间是 250 毫秒。
  • 很高兴能帮上忙。延迟时间由您决定,我对每次搜索都进行网络请求,因此保存网络数据和性能非常重要。甚至需要自定义缓存逻辑。如果需要,请参考轻量级缓存:developer.android.com/reference/android/util/LruCache
  • 作为一个问题,最后一次 onTextChanged 调用的计时器将继续完成它的工作,并且不会停止
  • 你能说清楚一点,你的意思是mSearchTask没有取消吗?
  • 没错就是这样
【解决方案2】:

如果输入的两个字符之间的时间差大于特定时间,则您可以避免搜索时间滞后,然后您开始在列表中搜索以进行更新productListAdapter,如果没有,则保持空闲状态。

这里是源代码:

        startTime = System.currentTimeMillis();
        endTime = System.currentTimeMillis();
        searchBox.addTextChangedListener(new TextWatcher() {

        @Override
        public void beforeTextChanged( CharSequence charSequence, int i, int i1, int i2) {

        }

        @Override
        public void onTextChanged(final CharSequence charSequence, int i, int i1, int i2) {
            endTime = System.currentTimeMillis();
            if(endTime - startTime >= 1000) {
                ArrayList<ProductInformation> newList = new ArrayList<>();
                for (ProductInformation info : currentList)
                    if (info.getName().contains(charSequence))
                        newList.add(info);
                productListAdapter.setNewData(newList);
            }
            startTime = endTime;
        }

        @Override
        public void afterTextChanged(Editable editable) {

        }
    });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-27
    • 1970-01-01
    • 1970-01-01
    • 2011-11-18
    • 2021-12-03
    • 2015-02-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多