猿问

EditText在ListView中滚动时丢失内容

我有一个带有EditText的列表项,我不知道会有多少个项。我在EditText中输入一些文本,然后向下滚动ListView时遇到问题,再次向上滚动后,第一个EditText中没有文本,或者ListView中其他EditText中有一些文本。


我已经尝试过TextWatcher,并将数据保存到数组中,但是问题是ListView中返回的视图位置并非总是正确的,因此我从数组中丢失了一些数据。-.-


如何在ListView中检测正确的视图位置?


例如:


如果我在ListView中有10个项目,并且当前只有其中5个可见。适配器返回位置从0到4 ...没关系。当我向下滚动项目6的位置是0 ... wtf?我从位置0的数组中丢失数据:)


我正在使用ArrayAdapter。


请帮忙。


这是一些代码:


public View getView(int position, View convertView, ViewGroup parent) {


    tmp_position = position;


    if (convertView == null) {


        holder = new ViewHolder();


        LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        convertView = vi.inflate(R.layout.element_in_game, null);


        holder.scoreToUpdate = (EditText) convertView

                .findViewById(R.id.elementUpdateScore);


        holder.scoreToUpdate.addTextChangedListener(new TextWatcher() {


            @Override

            public void onTextChanged(CharSequence s, int start,

                    int before, int count) {

                scoresToUpdate[tmp_position] = s.toString();

            }


            @Override

            public void beforeTextChanged(CharSequence s, int start,

                    int count, int after) {


            }


            @Override

            public void afterTextChanged(Editable s) {


            }

        });


        initScoresToUpdateEditTexts(holder.scoreToUpdate, hint);


        convertView.setTag(holder);


    } else {


        holder = (ViewHolder) convertView.getTag();


        holder.scoreToUpdate.setText(scoresToUpdate[tmp_position]);


    }


    return convertView;

}


收到一只叮咚
浏览 710回答 3
3回答

红颜莎娜

您应该按以下方式尝试:if (convertView == null) {        holder = new ViewHolder();        LayoutInflater vi = (LayoutInflater)            getSystemService(Context.LAYOUT_INFLATER_SERVICE);        convertView = vi.inflate(R.layout.element_in_game, null);        holder.scoreToUpdate = (EditText) convertView                .findViewById(R.id.elementUpdateScore);        convertView.setTag(holder);    } else {        holder = (ViewHolder) convertView.getTag();    }   //binding data from array list   holder.scoreToUpdate.setText(scoresToUpdate[position]);   holder.scoreToUpdate.addTextChangedListener(new TextWatcher() {            @Override            public void onTextChanged(CharSequence s, int start,                    int before, int count) {                //setting data to array, when changed                scoresToUpdate[position] = s.toString();            }            @Override            public void beforeTextChanged(CharSequence s, int start,                    int count, int after) {            }            @Override            public void afterTextChanged(Editable s) {            }        });    return convertView;}说明:ListView的回收行为实际上会在视力不佳时擦除与其行项目绑定的所有数据。因此,无论需要从哪个方向重新绑定数据,每一个新的行都会出现。另外,当EditText文本更改时,还必须将值保留在某些数据结构中,因此稍后再次进行行数据绑定时,可以提取位置数据。您可以使用数组ArrayList来保留edittext数据,也可以用于绑定数据。Recyclerview Adapter中使用类似的行为,在逻辑背后,您需要了解适配器的行数据的数据绑定。

繁花如伊

如果只有10行,请不要理会ListView。只需将它们垂直放置LinearLayout并用包裹即可,ScrollView这将为您节省一些麻烦。如果您要拥有数十行或数百行,我建议您想出比行中的EditText窗口小部件更好的UX范例 ListView。话虽这么说,感觉就像您没有正确处理行回收,或没有意识到行被回收。如果您的中有10个项目ListAdapter,并且只有空间显示5个带有EditText小部件的行,则EditText当用户滚动到底部时,不应显示10 个小部件。您应该以5-7结束-屏幕上的那个,或者当用户下一次滚动时,另外一个或两个可以回收。这个免费的摘录从我的书一个经过创建自定义子类的过程ArrayAdapter,并得到回收利用工作。它还涵盖了使用RatingBar用户输入的交互式行。这比起来容易得多EditText,因为您只需要担心单击事件。欢迎您尝试使用EditText小部件和TextWatcher侦听器扩展该技术,但我不是粉丝。
随时随地看视频慕课网APP

相关分类

Android
我要回答