EditText在ListView中滚动时丢失内容

Vel*_*jko 12 android listview android-edittext

我有包含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;
}
Run Code Online (Sandbox Code Playgroud)

Ana*_*ari 16

你应该尝试这样的方式如下:

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;
}
Run Code Online (Sandbox Code Playgroud)

说明:ListView的回收行为,实际上是在超出视觉范围时使用其Row Item擦除所有数据绑定.因此,每个新行都会从您需要再次绑定数据的任何方向进入.此外,当EditText文本更改时,您还必须在某些数据结构中保留值,因此稍后再次对行数据进行绑定,您可以提取位置数据.您可以使用数组ArrayList来保存edittext数据,也可以用来绑定数据.

类似的行为在Recyclerview Adapter中使用,在逻辑背后需要了解适配器行数据的数据绑定.


小智 12

你可以改用setOnFocusChangeListener.在我的情况下,我有可扩展的列表,它似乎很好:)像这样:

holder.count.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        public void onFocusChange(View v, boolean hasFocus) {
            if (!hasFocus) {
                EditText et =(EditText)v.findViewById(R.id.txtCount);
                myList.get(parentPos).put(childPos,
                        et.getText().toString().trim());
            }
        }
    });
Run Code Online (Sandbox Code Playgroud)


Com*_*are 5

如果你只有10行,不要打扰ListView.只需将它们放在垂直方向LinearLayout并将其包裹在一个中ScrollView,这样可以省去一些麻烦.

如果你要有几十行或几百行,我建议你提出一个比行中的EditText小部件更好的UX范例 ListView.

所有这一切,感觉就像你没有正确处理你的行回收,或者不知道行被回收.如果您有10个项目ListAdapter,并且只有空间可以显示5行EditText小部件,那么EditText当用户滚动到底部时,您不应该使用10 个小部件.您应该使用5-7 - 屏幕上的那些,以及当用户下一个滚动时可能还有另外一个或两个用于回收.

这个免费的摘录我的书一个经过创建自定义子类的过程ArrayAdapter,并得到回收利用工作.它还包括使用RatingBarfor用户输入的交互式行.这比a容易得多EditText,因为你只需要点击事件就可以了.欢迎您尝试使用EditText小部件和TextWatcher听众来扩展该技术,但我不是粉丝.


bic*_*ter 5

我有一个相关的问题,我解决了。我的每一行ListView都有一个不同的视图(它包含不同的控件。EditView、ImageView、TextView)。我希望在这些控件中输入或选择的数据即使在控件滚出屏幕时也能保留下来。我使用的解决方案是ArrayAdapter像这样实现以下方法:

public int getViewTypeCount() {
    return getCount();
}

public int getItemViewType(int position) {
    return position;
}
Run Code Online (Sandbox Code Playgroud)

这将确保在getView()被调用时它传递的View实例getView()与第一次调用时返回的实例相同。

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

  if (convertView != null)
    return convertView;
  else
  // create new view
}
Run Code Online (Sandbox Code Playgroud)