Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/231.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 自定义ListView适配器。TextChangedListener调用错误的EditText_Android_Listview_Android Edittext_Adapter - Fatal编程技术网

Android 自定义ListView适配器。TextChangedListener调用错误的EditText

Android 自定义ListView适配器。TextChangedListener调用错误的EditText,android,listview,android-edittext,adapter,Android,Listview,Android Edittext,Adapter,我有一个带有自定义适配器的旅行者列表,它由两个EditText组成——edtFirstName和edtLastName。我希望当用户输入文本时将更改保存到列表,当单击“下一步”按钮时将此列表发送到其他活动 我的代码: public class TravellersAdapter extends BaseAdapter { private List<Traveler> itemsList; private LayoutInflater inflater; private

我有一个带有自定义适配器的旅行者列表,它由两个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;
  }
}
公共类TravellersAdapter扩展了BaseAdapter{
私人物品清单;
私人充气机;
私人活动语境;
公共TravelersAdapter(活动上下文、列表项列表){
超级();
this.itemsList=itemsList;
this.context=上下文;
充气器=充气器。从(上下文);
}
public int getCount(){return itemsList.size();}
公共对象getItem(inti){returnitemslist.get(i);}
公共视图getView(最终整数位置、视图视图、视图组视图组){
如果(视图==null){
视图=充气机。充气(R.layout.traveller\u项目,空);
}
Traveler currentItem=(Traveler)getItem(位置);
EditText FirstName视图=(EditText)视图.findViewById(R.id.edtFirstName);
addTextChangedListener(新的TextWatcher(){
public void PostTextChanged(可编辑){
currentItem.setFirstName(可编辑的.toString());
}
});
返回视图;
}
}
例如,列表项列表由5项组成。当我编辑2-4个元素时,一切正常,但当我编辑分配给列表中所有元素的第一个或最后一个元素编辑值时。在dubugger中,我看到方法
PostTextChanged
调用了5次,调用的
位置值不同。

如何修复它?

getView方法中,参数position给出了新创建的子视图的位置,而不是单击的子视图的位置

使用此选项可获得正确的位置:

final int actual_position = myList.getPositionForView((View) v.getParent());
onClick中(视图v)onClickListener
的code>。在您的情况下,必须为该EditText实现onTextChangedListener

在这里:

myList是列表视图


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

getView方法中,参数position给出了新创建的子视图的位置,而不是单击的子视图的位置

使用此选项可获得正确的位置:

final int actual_position = myList.getPositionForView((View) v.getParent());
onClick中(视图v)onClickListener
的code>。在您的情况下,必须为该EditText实现onTextChangedListener

在这里:

myList是列表视图


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

之所以出现此问题,是因为视图是可重用的(这是Android API设计的)。因此,最终您可以为同一文本视图分配多个文本观察者。当文本视图中的文本发生更改时,所有指定的观察者都会被激发

一个快速解决方案(如果列表很长,比如说1000多个项目,那么这不是最佳方案)是有一个
Traweller->TextWatcher
的地图

然后在getView()内部可以执行以下操作(伪代码):

  • 如果此
    Traweller
  • 如果map没有,则创建一个新的
    TextWatcher
    ,放入map并分配给
    EditText
  • 否则,将
    TextWatcher
    EditText
    中分离并从映射中删除
  • 创建一个新的
    TextWatcher
    ,放入地图并分配给
    EditText

    • 之所以会出现这个问题,是因为视图是可重用的(这是安卓API设计的)。因此,最终您可以为同一文本视图分配多个文本观察者。当文本视图中的文本发生更改时,所有指定的观察者都会被激发

      一个快速解决方案(如果列表很长,比如说1000多个项目,那么这不是最佳方案)是有一个
      Traweller->TextWatcher
      的地图

      然后在getView()内部可以执行以下操作(伪代码):

      • 如果此
        Traweller
      • 如果map没有,则创建一个新的
        TextWatcher
        ,放入map并分配给
        EditText
      • 否则,将
        TextWatcher
        EditText
        中分离并从映射中删除
      • 创建一个新的
        TextWatcher
        ,放入地图并分配给
        EditText

      在屏幕中再创建一个名为
      invivisbleEt
      的不可见的
      EditText
      。 并在
      addTextChangedListener中执行以下操作

      firstNameView.addTextChangedListener(new TextWatcher() {
      
          @Override
          public void afterTextChanged(Editable editable) {
              if(!firstNameView.isFocused())
                  currentItem.setFirstName(editable.toString());
          }
      
      });
      
      还可以在
      ListView
      对象的
      onCreate
      方法中添加此代码

      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) {
          }
      });
      

      在屏幕中再创建一个不可见的
      EditText
      ,名称为
      invivisibleet
      。 并在
      addTextChangedListener中执行以下操作

      firstNameView.addTextChangedListener(new TextWatcher() {
      
          @Override
          public void afterTextChanged(Editable editable) {
              if(!firstNameView.isFocused())
                  currentItem.setFirstName(editable.toString());
          }
      
      });
      
      还可以在
      ListView
      对象的
      onCreate
      方法中添加此代码

      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) {
          }
      });
      

      您的firstNameView可循环用于多个项目。您的currentItem也是。您的firstNameView会被回收用于多个项目。您当前的项目以及。