RecyclerView中监听EditText变化的BUG的解决方法

需求:有一个列表,列表中有一个edittext(只能输整形),外部有一个整形变量Int,每次改变列表中其中一项的edittext的值时,外部的Int都会改变。

既然这样,我们就需要对edittext进行addTextChangedListener监听,一般做法是在afterTextChanged中对外部进行循环累加,但是想想,每一次你改变edittext都要进行一次时间复杂度为n的循环的话,想想就觉得这个算法很那啥,所以我想了另一个算法,每次改变其中一个item的值时,用总的值减去原item的edittext中的值加上item的edittext新输入的值,这样的复杂度为1,看着就很舒服。

但是这样也引出了一个问题,就是今天要说的BUG

我要讲的BUG是RecyclerView导致数据错乱的问题

我要讲的BUG是RecyclerView导致数据错乱的问题

我要讲的BUG是RecyclerView导致数据错乱的问题

重要事情说三遍

你想想,对于addTextChangedListener这个方法,你每次对edittext进行setText操作后都会调用这个方法,不巧的是recyclerview是复用容器,数据超出可用的容器时,会对edittext进行复用,也就是说,我们本身只想在addTextChangedListener中去监听手动改变edittext的情况,而recyclerview重复调用setText也会导致默认调用addTextChangedListener而会产生严重的数据错乱。

举个栗子,对我的需求原本是做这样的操作。

edtItem.addTextChangedListener(new TextWatcher() {

        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
             // todo 获取到edit改变前的数字
             String befour = edtItem.getText().toString();
        }

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

        }

        @Override
        public void afterTextChanged(Editable editable) {
             // todo 获取到edit改后的数字
             String now = edtItem.getText().toString();
        }
      });

这样拿到当前Item改变前的数字和改变后的数字,传给外部(传的做法我这没写,可以用观察者),然后外部总int - befour + now 就能获取到新的总数。

这逻辑看是完美,但是recyclerview帮你settext时,你的befour就是复用前的item中的数,而now就是新settext上去的数。
简单来说,我们要的效果是手动修改editText时才进行int - befour + now步骤,而现在你光滑动就莫名其妙进行int - 复用前item的数 + 复用后item的数。

那我们就需要解决一个问题,只有手动修改edittext时,才进行正确的操作,滑动时,不进行操作
其实我以前有说过reyclerview不能直接对它的容器进行操作(也就是viewholder),而应该对它的数据进行操作。所以这里我们改成这样的话,就不会受到滑动更新数据的影响。

edtItem.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
             // todo 获取到edit改变前的数字
             String befour = data;
        }

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

        }

        @Override
        public void afterTextChanged(Editable editable) {
             // todo 获取到edit改后的数字
             data = edtItem.getText().toString();
             String now = data ;
        }
      });

data是adapter传给viewholder的数据。这样写的话在beforeTextChanged方法中获取的就不是复用前item的数据,而是当前的数据。所以你滑动时发现befour 和now 会是一样,这时就不用进行更改总数的操作,而手动改变editText时befour 和now 是不一样的。

总结

可能你看不懂我的需求和例子,说明你没碰到过这样的情况(列表的edittext影响外部某个状态),我也不太好解释,但是你基本会碰到过数据错乱的情况,这就是我要说的。

在RecyclerView中,不管你要做什么操作,不要直接对容器(ViewHolder)操作,而是对数据进行操作。

补充一点java的常识

如果你传的是对象的话,这里对形参的改变,实参也会变,但是传基本数据类型的话,你变形参是不会影响实参的,所以不管有多少个数据,在viewholder中最后应该传入对象而不是基本数据类型.

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

您可能感兴趣的文章:

  • Android编程实现实时监听EditText文本输入的方法
  • Android编程实现EditText字数监听并显示的方法
  • EditText监听方法,实时的判断输入多少字符
  • Android开发中给EditText控件添加TextWatcher监听实现对输入字数的限制(推荐)
  • Android EditText 实现监听实例
  • 全面解析Android中对EditText输入实现监听的方法
  • Android编程实现监听EditText变化的方法
(0)

相关推荐

  • 全面解析Android中对EditText输入实现监听的方法

    在 Android design support 包中提供了一种在输入不合适字符时一直显示的提示方式来显示,现在已经开始在更多的应用上被使用了:这些 Android app 在显示他们的错误提示时采用的不同的方式常常让人感觉非常的不和谐. 即这个一直显示的错误消息是在 TextInputLayout 中的 EditText 周围的.这也是,作为一个奖励,提供了材料设计风格中,活泼的浮动标签在一个 APP 的用户体验中常常是最无聊的部分. 这里来讨论如何在你的输入表单上去创建一个通用的.可重用的组

  • Android EditText 实现监听实例

    我们要实现:当EditText的Text改变时,我们希望得到通知,但是可惜的是Android并没有这个监听器,也就无从得知变化了,但我们可以使用TextWatcher类可以帮助我们来实现这个功能. 现有一个id = edit的EditText. 1.定义一个TextWatcher的实例. private TextWatcher watcher = new TextWatcher(){ @Override public void afterTextChanged(Editable s) { //

  • Android编程实现EditText字数监听并显示的方法

    本文实例讲述了Android编程实现EditText字数监听并显示的方法.分享给大家供大家参考,具体如下: 在开发应用的时候,经常会限制用户输入的字数,比如发表评论或者其它什么的,下面来个简单的demo EditText et_content;//定义一个文本输入框 TextView tv_num;// 用来显示剩余字数 int num = 10;//限制的最大字数 et_content = (EditText) findViewById(R.id.et_content); tv_num = (

  • Android开发中给EditText控件添加TextWatcher监听实现对输入字数的限制(推荐)

    做这个功能是因为开发项目的时候,由于后台接口的一些参数的值的长度有要求,不能超过多少个字符,所以在编辑框中输入的字符是要有限制的. 下面就来看一下demo的实现过程: 首先,在xml控件中放置一个EditText控件,然后初始化该控件并对该控件添加文本监听.xml自己简单的设计一下,代码较为简单,直接上代码: package com.example.edittext; import android.app.Activity; import android.os.Bundle; import an

  • Android编程实现实时监听EditText文本输入的方法

    本文实例讲述了Android编程实现实时监听EditText文本输入的方法.分享给大家供大家参考,具体如下: 平时在做Android开发过程中经常要用到EditText,有时候可能需要监听你在TextView中输入的字数的状态和变化,以便于我们能做相应的提示和操作.我们可以通过下面的方式来实现. class EditChangedListener implements TextWatcher { private CharSequence temp;//监听前的文本 private int edi

  • Android编程实现监听EditText变化的方法

    本文实例讲述了Android编程实现监听EditText变化的方法.分享给大家供大家参考,具体如下: 监听EditText中的内容的变化.在EditText没有找到一个setOnxxxx的方法.百度了一下,原来在EditText中有一个方法addTextChangedListner(TextWatcher watcher)方法,用他可以时时监听EditText的内容变化.TextWatcher是一个接口类,所以必须实现TextWatcher里的抽象方法: 当EditText里面的内容有变化的时候

  • EditText监听方法,实时的判断输入多少字符

    最近在写一个小项目,其中有一点用到了显示EditText中输入了多少个字符,像微博中显示剩余多少字符的功能.在EditText提供了一个方法addTextChangedListener实现对输入文本的监控.下边是我自己写的一个Demo. 代码实现: 布局文件main.xml [html] view plain copy <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:androi

  • RecyclerView中监听EditText变化的BUG的解决方法

    需求:有一个列表,列表中有一个edittext(只能输整形),外部有一个整形变量Int,每次改变列表中其中一项的edittext的值时,外部的Int都会改变. 既然这样,我们就需要对edittext进行addTextChangedListener监听,一般做法是在afterTextChanged中对外部进行循环累加,但是想想,每一次你改变edittext都要进行一次时间复杂度为n的循环的话,想想就觉得这个算法很那啥,所以我想了另一个算法,每次改变其中一个item的值时,用总的值减去原item的e

  • React和Vue中监听变量变化的方法

    React 中 本地调试React代码的方法 yarn build 场景 假设有这样一个场景,父组件传递子组件一个A参数,子组件需要监听A参数的变化转换为state. 16之前 在React以前我们可以使用 componentWillReveiveProps 来监听 props 的变换 16之后 在最新版本的React中可以使用新出的 getDerivedStateFromProps 进行props的监听, getDerivedStateFromProps 可以返回 null 或者一个对象,如果

  • vue在App.vue文件中监听路由变化刷新页面操作

    在路由跳转时,会出现页面需要重新刷新一遍才能获取数据加载页面,这时添加一个监听器,如果跳转到页面刷新一次. export default { name: 'App', provide(){ return{ reload:this.reload } }, data(){ return { isRouterAlive:true, } }, //监听器 watch: { // 方法1 '$route' (to, from) { //监听路由是否变化 // console.log(999) if(to.

  • Vue 实时监听窗口变化 windowresize的两种方法

    下面给大家分享两种方法来介绍Vue 实时监听窗口变化 windowresize,具体内容如下所示: 方法一: First-step : 定义变量 data(){ return{ formLabelWidth : '123px' } }, Second-step:   根据生命周期 在mounted 中绑定 窗口变化 mounted(){ const that = this window.onresize = () => { return (() => { window.screenWidth

  • vue使用element-ui的el-input监听不了回车事件的解决方法

    原因 今天在使用element-ui时,el-input组件监听不了回车事件,如下代码没有想要的效果: <el-input class="search-input" placeholder="请输入内容" v-model="searchText" @keyup.enter="search()"></el-input> 原因应该是element-ui自身封装了一层input标签之后影响了事件的监听,在el

  • Android中监听未接来电的2种方法

    这里主要是总结一下如何监听有未接来电的问题   1.1 使用广播接收器 BrocastReceiver 实现思路 : 静态注册监听android.intent.action.PHONE_STATE 的广播接收器 当手机的状态改变后将会触发 onReceive. 手机的状态分为CALL_STATE_RINGING(响铃中),CALL_STATE_IDLE(空闲),CALL_STATE_OFFHOOK(忙音). 也就是说当你没有任何电话是,状态是 IDLE ,当接到电话时是 OFFHOOK ,电话结

  • RecyclerView中使用CheckBox出现勾选混乱的解决方法

    熟悉RecyclerView的人应该都知道,RecyclerView使用了复用机制,当在RecyclerView中得每一项都添加一个CheckBox时,勾选当前页面的几个CheckBox会发现下面还有其他的CheckBox也被勾选了,今天我们就来讨论一下如何解决这个问题. 首先当然是创建一个项目,然后在activity_main中添加一个RecyclerView控件,当然,在这之前,我们需要先添加RecyclerView的依赖,如下图: 然后 开始编辑activity_main: <?xml v

  • ff下JQuery无法监听input的keyup事件的解决方法

    复制代码 代码如下: $(document).ready(function(){    $('#news_title').bind('input',fun).bind('keyup',fun);}); //function listvar fun=function(){    value=$(this).val();    $('.prev').text(value);} 注: bind('input',fun)  用于ff下keyup bind('keyup',fun) 用于ie

  • vue中是怎样监听数组变化的

    我们知道通过Object.defineProperty()劫持数组为其设置getter和setter后,调用的数组的push.splice.pop等方法改变数组元素时并不会触发数组的setter,这就会造成使用上述方法改变数组后,页面上并不能及时体现这些变化,也就是数组数据变化不是响应式的(对上述不了解的可以参考这篇文章).但实际用vue开发时,对于响应式数组,使用push.splice.pop等方法改变数组时,页面会及时体现这种变化,那么vue中是如何实现的呢? 通过vue源码可以看出,vue

随机推荐