Android 自定义ListView适配器。TextChangedListener调用错误的EditText
我有一个带有自定义适配器的旅行者列表,它由两个EditText组成——edtFirstName和edtLastName。我希望当用户输入文本时将更改保存到列表,当单击“下一步”按钮时将此列表发送到其他活动 我的代码: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
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会被回收用于多个项目。您当前的项目以及。