我有一个自定义ArrayAdapter实现,如下所示:
private final LayoutInflater inflater;
private final Context mContext;
private final int resource;
private ListObject item;
public CheckListAdapter(Context cx, int res, List<ListObject> list){
super(cx,res,list);
resource=res;
mContext=cx;
inflater=LayoutInflater.from(cx);
}
@Override
public View getView(int position, View convertView, ViewGroup container) {
convertView = (LinearLayout) inflater.inflate(resource, null);
item = getItem(position);
TextView slotNoView = (TextView)convertView.findViewById(R.id.itemSlotNo);
TextView itemNameView = (TextView)convertView.findViewById(R.id.itemnameview);
TextView itemIdView = (TextView)convertView.findViewById(R.id.itemIdView);
String slotNo = item.getSlotNo();
String itemName = item.getItemName();
slotNoView.setText(slotNo+".");
itemNameView.setText(itemName);
itemIdView.setText(item.getId());
EditText value = (EditText)convertView.findViewById(R.id.value);
value.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
String new6amVal = value.getText().toString();
Log.d("ListView Position",Integer.toString(position));
Log.d("Item ID: ",item.getId());
Log.d("Item value: ",value.getText().tostring());
}
});
return convertView;
}
创建适配器并将其发送到列表视图时,所有TextView都会正确填充。但是当我在任何列表项的EditText中进行更改时,更改仅反映在第一个列表项EditText中。当我从TextChangeListener中记录getView方法中获得的位置变量时,我可以看到position的值始终为0.如何从getView方法中获取每个列表项的正确位置值?
我还尝试使用OnFocusChangeListener来检查位置的值,但返回的值始终是第一个位置。
答案 0 :(得分:2)
您应该为适配器使用推荐的ViewHolder
模式,并将您的位置设置为final
。如果这不起作用,那么我建议您创建一个自定义TextWatcher
类来跟踪位置本身。这是一些示例代码。
对于ViewHolder模式,创建一个扩展RecyclerView.ViewHolder并在那里查找所有视图的类
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView slotNoView;
TextView itemNameView;
TextView itemIdView;
EditText value;
public MyViewHolder(View itemView) {
super(itemView);
slotNoView = (TextView) itemView.findViewById(R.id.itemSlotNo);
itemNameView = (TextView)itemView.findViewById(R.id.itemnameview);
itemIdView = (TextView) itemView.findViewById(R.id.itemIdView);
value = (EditText) itemView.findViewById(R.id.value);
}
}
然后在getView
适配器方法中,仅当convertview为null时才创建ViewHolder的新实例。像这样(记得要position
final
)
@Override
public View getView(final int position, View convertView, ViewGroup container) {
MyViewHolder viewHolder;
if(convertView == null){
convertView = inflater.inflate(resource, container, false);
}
viewHolder = new MyViewHolder(convertView);
item = getItem(position);
String slotNo = item.getSlotNo();
String itemName = item.getItemName();
viewHolder.slotNoView.setText(slotNo+".");
viewHolder.itemNameView.setText(itemName);
viewHolder.itemIdView.setText(item.getId());
viewHolder.value.addTextChangedListener(new TextWatcher() {
//implement your stuff
...
}
}
如果这不起作用,请创建一个实现TextWatcher
的自定义抽象类,该类将知道该位置,然后在其中实现一个方法getPosition()
,以便在你需要它。您可以在构造函数中传递位置。例如:
private abstract class PositionAwareTextWatcher implements TextWatcher{
private int position;
public PositionAwareTextWatcher(int position){
this.position = position;
}
public int getPosition(){
return this.position;
}
}
然后在您设置TextWatcher的getView
中,按照这样使用
viewHolder.value.addTextChangedListener(new PositionAwareTextWatcher(position) {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
String new6amVal = value.getText().toString();
Log.d("ListView Position",Integer.toString(getPosition()));
Log.d("Item ID: ",item.getId());
Log.d("Item value: ",value.getText().tostring());
}
};