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

TextWatcher.onTextChanged打了很多次电话

太叔景曜
2023-03-14

我读了一些关于这个问题的帖子,但找不到一个彻底的答案。我有一个有3行的ListView,每行包含一个TextView和一个EditText,还有一个扩展BaseAdapter的自定义适配器。

这是适配器的getView函数:

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    if(convertView == null) {
        LayoutInflater inflater = mActivity.getLayoutInflater();
        convertView = inflater.inflate(R.layout.settings_column, null);

        mTxtValue = (EditText) convertView.findViewById(R.id.settings_value);

        mTxtValue.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                if (tryParseInt(s.toString())) {
                    RowsList.get(position).setDuration(Integer.parseInt(s.toString()));
                    System.out.println("position: " + position + ", value: " + s.toString());
                }
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });
    }

    ColorColumn colorColumn = RowsList.get(position);
    mTxtValue.setText(String.valueOf(colorColumn.getDuration()));

    return convertView;
}

如您所见,每次值发生变化时,我都尝试用EditText值更新名为RowsList的ColorColumn列表。由于某种原因,onTextChanged方法被调用了太多次,因此在列表中放置了错误的数据。EditText的inputType是< code > Android:input type = " number | textNoSuggestions " ,如另一个线程中所建议的。

这是启动活动并填充ListView时显示的日志:

10-27 19:30:15.238 19845-19845/com.busalert.www.busalert I/System.out: position: 0, value: 1
10-27 19:30:15.242 19845-19845/com.busalert.www.busalert I/System.out: position: 0, value: 2
10-27 19:30:15.244 19845-19845/com.busalert.www.busalert I/System.out: position: 0, value: 3
10-27 19:30:15.317 19845-19845/com.busalert.www.busalert I/System.out: position: 0, value: 3
10-27 19:30:15.325 19845-19845/com.busalert.www.busalert I/System.out: position: 1, value: 2
10-27 19:30:15.333 19845-19845/com.busalert.www.busalert I/System.out: position: 2, value: 3
10-27 19:30:15.346 19845-19845/com.busalert.www.busalert I/System.out: position: 0, value: 3
10-27 19:30:15.350 19845-19845/com.busalert.www.busalert I/System.out: position: 0, value: 2
10-27 19:30:15.353 19845-19845/com.busalert.www.busalert I/System.out: position: 0, value: 3
10-27 19:30:15.388 19845-19845/com.busalert.www.busalert I/System.out: position: 0, value: 3
10-27 19:30:15.394 19845-19845/com.busalert.www.busalert I/System.out: position: 0, value: 2
10-27 19:30:15.398 19845-19845/com.busalert.www.busalert I/System.out: position: 0, value: 3

正如你所能做的,每个位置的第一次出现都是正确的,但还有9次额外的呼叫。

这是当用户第一次输入编辑文本时出现的日志:

10-27 19:30:21.226 19845-19845/com.busalert.www.busalert I/System.out: position: 0, value: 3
10-27 19:30:21.230 19845-19845/com.busalert.www.busalert I/System.out: position: 0, value: 2
10-27 19:30:21.231 19845-19845/com.busalert.www.busalert I/System.out: position: 0, value: 3
10-27 19:30:21.356 19845-19845/com.busalert.www.busalert I/System.out: position: 0, value: 3
10-27 19:30:21.357 19845-19845/com.busalert.www.busalert I/System.out: position: 0, value: 2
10-27 19:30:21.363 19845-19845/com.busalert.www.busalert I/System.out: position: 0, value: 3
10-27 19:30:21.369 19845-19845/com.busalert.www.busalert I/System.out: position: 0, value: 3
10-27 19:30:21.370 19845-19845/com.busalert.www.busalert I/System.out: position: 0, value: 2
10-27 19:30:21.376 19845-19845/com.busalert.www.busalert I/System.out: position: 0, value: 3

同样,9个额外的电话(应该有0个电话,因为没有什么真正改变)。

从现在开始,每次更改都会根据需要生成一个调用。

更新:我创建了一个布尔数组来指示TextWatcher是否已经被添加到每个EditText中,因此我确保每个编辑器只有一个。添加之后,当活动开始时有6个调用(额外3个),当我第一次单击EditText时没有调用。这是新日志(2、3和4是多余的):

10-27 20:02:49.765 29637-29637/com.busalert.www.busalert I/System.out: position: 0, value: 1
10-27 20:02:49.767 29637-29637/com.busalert.www.busalert I/System.out: position: 0, value: 2
10-27 20:02:49.769 29637-29637/com.busalert.www.busalert I/System.out: position: 0, value: 3
10-27 20:02:49.827 29637-29637/com.busalert.www.busalert I/System.out: position: 0, value: 3
10-27 20:02:49.834 29637-29637/com.busalert.www.busalert I/System.out: position: 1, value: 2
10-27 20:02:49.840 29637-29637/com.busalert.www.busalert I/System.out: position: 2, value: 3

共有2个答案

洪增
2023-03-14

另一种解决方案是检查字段(编辑文本或文本视图)是否为Dirty。

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                if (mTextView.isDirty())
                    doWork();
            }
曾成天
2023-03-14

问题是LisView元素正在被回收,因此旧的TextWatcher在回收行后仍然被附加。因此,每次调用getView时,都会添加一个新的TextWatcher,而旧的TextWatcher仍然附加到EditText。不幸的是,没有删除所有旧的TextWatcher附加的功能,因此唯一的解决方案是创建一个自定义的EditText,您可以在其中保留对所有TextWatcher的引用,然后创建一个自定义函数,在getView中回收View时将它们全部删除。

 类似资料:
  • 我知道这是Telegram的一个副本,它向webhook发送重复的POST JSON请求,并向webhoook发送重复的POST JSON请求。然而,这个问题没有任何充分的答案,因此: 我有一个PHP应用程序处理来自Telegram的webhook请求。然而,Telegram并没有看到webhook成功运行(尽管hurl.it清楚地显示,它在这样一个请求上发送了200条消息)。 因此,我让我的机器

  • 问题内容: 关于的简单代码。是SessionScoped Bean,是RequestScoped Bean 内 我的问题是被叫很多。会告诉我们该方法在什么阶段被调用。首次加载页面时,请在阶段6-进行约 5次 呼叫。该页面上有一个,因此我在其中键入一些内容,然后单击(命令按钮)。然后在阶段1-> 4期间再呼叫 12次 。每个阶段调用此方法 3-4次 。然后,此属性的get 方法的setter方法(即

  • 在此RDD上应用筛选器,并将相关行的范围移出:filter 在此RDD上应用筛选器,并将相关行的范围移出:filter 加入RDD:join 应用map阶段计算投资:map 应用GroupBy阶段根据所需视图对数据进行分组:GroupBy 应用map阶段来按照上述步骤中实现的分组聚合数据(例如跨时间段查看数据),并根据需要收集的resultset创建新对象:map 收集结果:收集 因此,如果用户想

  • 问题内容: 如何在一行中多次打印一个字符?这意味着我不能使用循环。 我正在尝试多次打印。 我尝试了这种方法,但是不起作用: 是变量。 问题答案: 您可以在同一行中进行打印,因此 可以 使用循环。而不是不添加换行符。 将打印:。

  • 我有一台4GB RAM和酷睿i5处理器的惠普笔记本电脑。在android studio下载页面中,已经指定建议使用4GB内存。但我的Android Studio仍然挂着,需要很多时间来回应。

  • 我是一名初出茅庐的程序员,在eclipse中直接使用Java。我试图让我的Java程序调用从http://dev.clojure.org/display/doc/Getting从Eclipse和逆时针文章开始。hello函数在通过逆时针插件启动的Clojure REPL中运行良好。当我试图从Java类执行hello函数时,会出现问题。 谷歌搜索发现,基本上有两种方法可以做到这一点:clojure。