1

我有带有自定义适配器的旅行者列表,其中包含两个 EditText - edtFirstName 和 edtLastName。我想要当用户输入文本时保存更改到列表,并且当下一个按钮单击时将此列表发送到另一个活动。

我的代码:

public class TravellersAdapter extends BaseAdapter {

  private List<Traveler> itemsList;
  private LayoutInflater inflater;
  private Activity context;

  public TravellersAdapter(Activity context, List<Traveler> itemsList) {
    super();
    this.itemsList = itemsList;
    this.context = context;
    inflater = LayoutInflater.from(context);
  }

  public int getCount() { return itemsList.size();  }

  public Object getItem(int i) {  return itemsList.get(i);  }

  public View getView(final int position, View view, ViewGroup viewGroup) {
    if (view == null) {
      view = inflater.inflate(R.layout.traveller_item, null);
    }
    Traveler currentItem = (Traveler) getItem(position);

    EditText firstNameView = (EditText) view.findViewById(R.id.edtFirstName);
    firstNameView.addTextChangedListener(new TextWatcher() {

      public void afterTextChanged(Editable editable) {
        currentItem.setFirstName(editable.toString());
      }

    });

    return view;
  }
}

例如 List itemsList 包含 5 个项目。当我编辑 2-4 个元素时一切正常,但是当我编辑第一个或最后一个元素时,编辑值分配给列表中的所有元素。在 dubugger 中,我看到该方法afterTextChanged调用了 5 次不同的position. 如何解决?

4

3 回答 3

3

getView方法中,参数position给出了新创建的childView的位置,而不是点击的 childView 的位置。

使用它来获得正确的位置:

final int actual_position = myList.getPositionForView((View) v.getParent());

在任何视图中onClick(View v);onClickListener在您的情况下,您必须为该 EditText 实现onTextChangedListener

这里:

myList是 ListView

v是您单击的视图,在本例中是父视图(myList)的子视图。

于 2012-10-01T10:02:07.750 回答
2

出现这个问题是因为视图是可重用的(这是 Android API 中的设计)。所以最终你可以为同一个文本视图分配超过 1 个文本观察者。当文本视图中的文本发生更改时,所有分配的观察者都会被触发。

一个快速的解决方法(如果列表真的很长,比如 1000 多个项目,则不是最佳的)是拥有一个Traweller -> TextWatcher.

然后在 getView() 你可以这样做(伪代码):

  • 检查地图是否有TextWatcher这个Traweller
  • 如果地图没有,则创建一个新的TextWatcher,放入地图并分配给EditText
  • 否则从地图中分离并TextWatcherEditText地图中删除
  • 创建一个新的TextWatcher,放入地图并分配给EditText
于 2012-10-01T10:11:04.593 回答
0

EditText在不可见的屏幕中再创建一个name invivisbleEt。并在addTextChangedListener

firstNameView.addTextChangedListener(new TextWatcher() {

    @Override
    public void afterTextChanged(Editable editable) {
        if(!firstNameView.isFocused())
            currentItem.setFirstName(editable.toString());
    }

});

onCreate还要在对象的方法中添加此代码ListView

lv.setOnScrollListener(new AbsListView.OnScrollListener() {

    //public boolean scrolling;

    @Override
    public void onScrollStateChanged(AbsListView absListView, int scrollState) {
        invivisbleEt.requestFocus();
    }

    @Override
    public void onScroll(AbsListView absListView, int i, int i1, int i2) {
    }
});
于 2016-05-13T13:59:10.480 回答